seekrit

Examples

A cookbook of patterns you can copy and adapt. Each recipe links to the guide that covers it in depth.

Almost everything here rests on two properties:

  • One encrypted secret set resolves the same way in every runtime — local dev, CI, a container, a Kubernetes pod, an agent sandbox — because they all decrypt through the same key grant.
  • Environments compose. An application environment is its own secrets plus the groups it pulls in, layered at runtime — so shared config lives in one place.

Agents get first-class treatment: because seekrit is zero-knowledge, an agent can use a secret it is never allowed to read.

Everyday: replace your .env file

Run any command with secrets injected

Stop keeping a plaintext .env in the repo. A service token carries its own org, app, and environment, so nothing else is needed:

export SEEKRIT_TOKEN=skt_…
seekrit run -- pnpm dev            # secrets injected into the child process
seekrit run -- ./migrate && ./serve

A local .env still works — it layers on top of the managed secrets, so you can override one value without touching the shared set:

group secrets  <  app-env secrets  <  .env file  <  process env      (highest wins)

See the CLI guide.

See exactly where each value came from

When a value isn't what you expect, --explain prints each variable's source layer to stderr (names only, never values):

seekrit run --explain -- true

Composability: share config across apps

One shared group, many apps

Put config that several apps share into a group, then compose it into each app's environments. Here an api and a web app share a database and cache:

# A shared group with a per-environment value set
seekrit group create --name "Shared infra" --slug shared-infra
seekrit group env create --group shared-infra --name Production --slug production
seekrit secrets set DATABASE_URL 'postgres://…' --group shared-infra --env production
seekrit secrets set REDIS_URL    'rediss://…'   --group shared-infra --env production

# Compose it into each app's production environment
seekrit env groups add --app api --env production --group shared-infra
seekrit env groups add --app web --env production --group shared-infra

# App-specific secrets live on the app environment and override the group
seekrit secrets set STRIPE_KEY 'sk_live_…' --app api --env production

Change DATABASE_URL once in the group and both apps pick it up. See Environments & groups.

Layer several groups with precedence

Compose more than one group and control precedence with --position (higher wins). App-env secrets still win over every group:

seekrit env groups add --app api --env production --group shared-infra --position 10
seekrit env groups add --app api --env production --group third-party  --position 20
seekrit env groups list --app api --env production      # inspect the order

Swap a single group's slice per boot

Group environments double as variants. Boot everything at dev but pull one group — say auth providers — from its staging slice, without a separate environment:

seekrit run --with auth-providers=staging -- pnpm dev

Overrides are fail-closed: you can only pull a slice you hold a key for. As a logged-in developer you hold them all; for a service token, pre-authorize the slice at creation with token create … --allow auth-providers=staging.

One secret set, every runtime

The same token in local dev, CI, and a container

Bind a token to one environment once, then hand it to every runtime — each resolves and decrypts identically:

# Local / CI — Node CLI
SEEKRIT_TOKEN=skt_… seekrit run -- ./deploy.sh

# GitHub Actions — SEEKRIT_TOKEN from the repo's secret store
#   - run: seekrit run -- ./deploy.sh

# Container / distroless — the static launcher, no Node required
SEEKRIT_TOKEN=skt_… seekrit-run -- ./start-server

See Service tokens, CI/CD & containers, and the seekrit-run launcher.

A container entrypoint that degrades gracefully

seekrit-run is a tiny static binary with no Node/OpenSSL/CA dependency, so it runs in distroless, alpine, and scratch. Fetching secrets is best-effort: if the token is missing or the API is unreachable, it warns and still runs your command with just .env + the live environment — so the same image works with or without seekrit wired up.

FROM gcr.io/distroless/static
COPY --from=seekrit /usr/local/bin/seekrit-run /usr/local/bin/seekrit-run
ENTRYPOINT ["seekrit-run", "--"]
CMD ["./start-server"]
caution

Inject at runtime, never at build time — secrets fetched during docker build can be baked into an image layer. seekrit-run only ever puts values into the child process's environment; nothing touches disk.

Built for agents

Let an agent provision a service end-to-end

Register the MCP server once, giving the agent an admin token so it can create structure headlessly:

SEEKRIT_TOKEN=skt_…  claude mcp add seekrit -- seekrit mcp

Now the agent drives seekrit as tools — a typical stand-up-a-service session:

  1. create_appcreate_env (production) — the data key is generated locally.
  2. set_secret for DATABASE_URL, API_KEY, … (encrypted on this machine).
  3. create_token bound to that env — a runtime token, auto-granted its keys.
  4. configure_project to write seekrit.json, then hand the runtime token to CI or a container.
  5. run_command -- pnpm test to verify the app boots with its secrets injected.

See the AI agents guide.

Use secrets the agent can't read

The zero-knowledge model means an agent can put a secret to work without its plaintext ever entering the conversation:

  • run_command resolves the environment, injects it into a child process, and returns only the exit code and output — the values never reach the agent.
  • export_env writes a gitignored file for tools that read .env.
  • get_secret returns metadata; it only decrypts into the response when you pass reveal: true.
run_command -- pnpm test          # values injected, never returned
caution

Revealing a secret puts its plaintext in the agent's context, where it may be logged or retained. Use run_command (or export_env) whenever the agent needs to use a secret rather than read it.

Ephemeral agent sandboxes

Give a throwaway sandbox exactly the secrets it needs through a short-lived, independently revocable token — no long-lived credentials in the environment:

# Stand up a scoped env + token for the sandbox
seekrit env create --app storefront --name "Sandbox 7f3" --slug sandbox-7f3
seekrit secrets set OPENAI_API_KEY 'sk-…' --app storefront --env sandbox-7f3
seekrit token create --name sandbox-7f3 --app storefront --env sandbox-7f3   # prints skt_…

# … the sandbox runs `seekrit-run -- ./agent`, decrypting locally …

seekrit token revoke skt_XXXXXXXX      # on teardown

The token self-decrypts (no passphrase) and can only reach the environment it was granted. See CI/CD & containers.

Dynamic credentials: short-lived Postgres logins

Mint a database login that auto-expires, and hand the URL straight to a tool. The password and its SCRAM verifier are generated on your machine — only the verifier is sent, so the plaintext never reaches seekrit or Postgres at rest:

psql "$(seekrit pg lease prod-db --ttl 30m)"

This composes with everything above: an agent or CI job can lease a 30-minute credential for one task instead of holding a standing database password. See Temporary access.