Self-hosted provisioner
Temporary-access targets choose where provisioning runs via the executor. By
default (in_do) the seekrit broker decrypts your database admin credential
transiently to run CREATE ROLE / DROP USER itself. The remote executor
moves that work into your network: the broker signs each command and sends it to
a seekrit-provisioner daemon you run, which holds the admin credential
locally. seekrit orchestrates but never sees it — pure zero-knowledge even for
provisioning.
The remote executor is for the Postgres and MySQL/MariaDB providers. SSH
certificate signing is in_do-only for now.
How it works
The broker holds only a shared HMAC key (wrapped to its per-org keypair, like any admin secret). Your database admin credential lives only on the daemon. Every command the broker sends is signed HMAC-SHA256; the daemon verifies the signature, rejects stale or replayed commands, and runs the already-rendered SQL.
broker (seekrit) your network
──────────────── ────────────
signs ProvisionCommand ──── POST ───▶ seekrit-provisioner ──▶ Postgres / MySQL
(HMAC, shared key) verify sig · freshness ·
replay · run SQL as admin
The credential you hand a consumer stays zero-knowledge as always — the consumer generates it and sends only a verifier. The daemon only ever handles the admin credential, which now never leaves your network.
1. Mint the shared key
seekrit provisioner keygen
# → a base64 key on stdout. Keep it secret.
Use the same value in both places below: --hmac-key when you register the
target, and SEEKRIT_PROVISIONER_HMAC_KEY on the daemon.
2. Register a remote target
The admin connection string does not go to seekrit here — only the HMAC key
is wrapped and uploaded. Point --provisioner-url at where the daemon will
listen.
KEY=$(seekrit provisioner keygen)
seekrit pg target add \
--name prod-db --host db.internal --database app \
--access readonly \
--executor remote \
--provisioner-url https://provisioner.internal:8088/ \
--hmac-key "$KEY"
seekrit mysql target add takes the same --executor remote --provisioner-url --hmac-key flags. For the readonly / readwrite presets, run the one-time
group-role setup SQL the command prints (Postgres) as a database admin.
3. Run the daemon
Run it where it can reach the database, holding the same key plus the real admin connection string:
docker run -d --name seekrit-provisioner -p 8088:8088 \
-e SEEKRIT_PROVISIONER_HMAC_KEY="$KEY" \
-e SEEKRIT_PROVISIONER_DATABASE_URL="postgres://admin:secret@db.internal:5432/app" \
seekritdev/provisioner:latest
Prebuilt multi-arch images (amd64 + arm64) are published to Docker Hub as
seekritdev/provisioner —
pin a release tag (e.g. :0.1.0) or :edge for the latest main. The image is
a single static binary on scratch — no OS, no shell. GET /healthz returns
{"ok":true} for liveness probes.
Environment
| Variable | Required | Default | Purpose |
|---|---|---|---|
SEEKRIT_PROVISIONER_HMAC_KEY | yes | — | Base64 shared key; must match the target's --hmac-key. |
SEEKRIT_PROVISIONER_DATABASE_URL | yes | — | Admin postgres://… or mysql://… string. Held only here. |
SEEKRIT_PROVISIONER_PROVIDER | no | inferred from URL | postgres or mysql, if ambiguous. |
SEEKRIT_PROVISIONER_DB_TLS | no | require | require or disable (local/plaintext DB). |
SEEKRIT_PROVISIONER_ADDR | no | 0.0.0.0:8088 | Listen address. |
SEEKRIT_PROVISIONER_MAX_SKEW_SECS | no | 300 | Freshness window (and replay-cache TTL). |
Lease as usual
Nothing changes for the consumer. seekrit pg lease prod-db mints a credential
exactly as with the in-DO executor — the difference is entirely in where the
CREATE ROLE ran.
The HMAC authenticates and integrity-protects every command regardless of transport, so plain HTTP behind your own ingress is safe. Still, front the daemon with TLS if it is reachable beyond localhost, so command contents stay confidential in transit. The daemon holds a privileged database credential — keep it on a private network and scope that credential to only what provisioning needs.
Security properties
- Authenticity — a missing or bad signature is rejected (
401) before any database work; verification is constant-time. - Anti-replay — commands outside a ±5-minute window are rejected (
400), and each nonce is single-use within that window. - Least exposure — the daemon runs only the SQL the broker rendered, returns no query results, and never logs the admin URL, the key, or the statements.