Dibbla Docs Get started Guides Workflows Changelog
Open Console
Reference · CLI

dibbla secrets

Create, read, and delete secrets — globally for the whole org or scoped to a single deployment. Values can be passed as arguments or piped from stdin.

dibbla secrets manages the secret store on the Dibbla platform. Secrets come in three scopes, and the narrowest one that matches wins:

  • Global — available to every deployment in the org. Omit --deployment.
  • Per-deployment — only injected into a single app. Set --deployment <alias>.
  • Per-service — only injected into one service of a multi-service app. Add --service <name> alongside --deployment.

Secrets are injected into deployments at runtime as environment variables. The CLI never logs values; set and get print only the secret’s content (or nothing).

To load a whole .env file at once instead of calling set per key, use secrets import.

dibbla secrets list

FlagPurpose
-d, --deployment <alias>List secrets attached to one deployment. Omit for global secrets.
-s, --service <name>Narrow to one service. Requires -d.
$dibbla secrets list
🌱 Retrieving secrets...
 
Found 2 secret(s) (global):
 
NAME                      DEPLOYMENT           SERVICE   UPDATED
----                      -----------          -------   ------
DATABASE_URL_MAIN         (global)             (all)     2026-04-14 10:23:01
STRIPE_KEY                (global)             (all)     2026-04-28 12:14:55
$dibbla secrets list --deployment my-api
🌱 Retrieving secrets...
 
Found 2 secret(s) (deployment 'my-api'):
 
NAME                      DEPLOYMENT           SERVICE   UPDATED
----                      -----------          -------   ------
DATABASE_URL_TODO         my-api               (all)     2026-04-28 13:01:12
WEBHOOK_SIGNING_SECRET    my-api               web       2026-04-25 09:42:18

dibbla secrets set

Create or update a secret. The value comes from the second positional argument or, if omitted, from stdin — useful when you don’t want the value in shell history.

FlagPurpose
<name> (positional, required)Secret name. Conventionally SCREAMING_SNAKE_CASE.
[value] (positional)Secret value. If omitted, read from stdin.
-d, --deployment <alias>Attach the secret to a single deployment. Omit for global.
-s, --service <name>Scope to one service of a multi-service app. Requires -d.
$dibbla secrets set STRIPE_KEY sk_live_...
🌱 Setting secret 'STRIPE_KEY'...
 
✅ Secret 'STRIPE_KEY' set
  Secret: STRIPE_KEY
# Avoid leaving the value in shell history
$echo "$STRIPE_KEY" | dibbla secrets set STRIPE_KEY
 
# Or read from a file
$dibbla secrets set TLS_CERT < cert.pem
$dibbla secrets set WEBHOOK_SIGNING_SECRET whsec_... --deployment my-api
🌱 Setting secret 'WEBHOOK_SIGNING_SECRET'...
 
✅ Secret 'WEBHOOK_SIGNING_SECRET' set
  Secret: WEBHOOK_SIGNING_SECRET
  Deployment: my-api
Be careful with shell history.

When you pass a secret as a positional argument, the full command is stored in your shell’s history file. Pipe via stdin (or read from a file) for anything more sensitive than a placeholder.

dibbla secrets import

Bulk-load every KEY=value from a .env-style file into the secret store in one shot — without a redeploy. This is the alternative to a while read loop around secrets set, and it keeps values out of your shell history.

FlagPurpose
<file> (positional, required)A .env-style file. See .env file format below.
-e, --env KEY=valueOverride a single key on top of the file. Repeatable.
-d, --deployment <alias>Import into one deployment. Omit for global secrets.
-s, --service <name>Scope to a single service. Requires -d.
--dry-runList the keys that would be set. No values, no network calls.

The file is the base layer and -e KEY=value flags override individual keys. If a key appears in more than one -e flag, the last one wins. This is the same env precedence dibbla run --env-file uses.

$dibbla secrets import ../secrets/.env.prod --deployment my-api
🌱 Importing 3 secret(s) into deployment my-api...
 
✅ imported 3 secret(s) into deployment my-api: API_KEY, DATABASE_URL, STRIPE_KEY
# File is the base layer; -e wins for that one key
$dibbla secrets import ../secrets/.env.prod \
  --deployment my-api \
  -e STRIPE_KEY=sk_live_rotated
$dibbla secrets import .env --deployment my-api --dry-run
🌱 Dry run — would import 3 secret(s) into deployment my-api:
  API_KEY
  DATABASE_URL
  STRIPE_KEY
 
No secrets were written (--dry-run).
$dibbla secrets import .env --deployment my-api
❌ Invalid secret name(s): 1BAD, my.key
  Names must match ^[a-zA-Z][a-zA-Z0-9_]{0,127}$
  Nothing was imported.

Every key is validated before anything is sent. Names must match ^[a-zA-Z][a-zA-Z0-9_]{0,127}$ — start with a letter, then letters, digits, and underscores. If any key in the file is invalid, the command names the offending keys, exits non-zero, and imports nothing; you never end up with half a file applied.

Values are never printed. Output is key names and a count, on both the success and the failure path.

Re-running is safe. The server upserts each secret, so an import is idempotent. If a write fails partway, the command stops, tells you which key failed and how many succeeded, and you can simply re-run it.

Keep the .env file outside your deploy directory.

secrets import reads the file client-side and sends the values over the authenticated API — the file itself is never uploaded. But a .env sitting in the directory you deploy is a separate problem: it is a pre-deploy guardrail blocker and is stripped from Dibbla-managed VCS. Keep the file somewhere else (dibbla secrets import ../secrets/.env.prod) or list it in .dibblaignore.

.env file format

The same parser backs secrets import, dibbla deploy --env-file, dibbla apps update --env-file, and dibbla run --env-file.

LineResult
KEY=valueThe basic form.
export KEY=valueAccepted — export is ignored.
# commentWhole-line comments are skipped, as are blank lines.
KEY=value # noteTrailing comments are stripped.
KEY=An empty string, not “unset”.
KEY=a=b=cSplit on the first =, so the value is a=b=c.
KEY="has spaces"Quotes are stripped. Double-quoted values may span lines.
KEY="pre $OTHER post"$VAR and ${VAR} are expanded — in double-quoted and unquoted values alike.
KEY='literal ${OTHER}'Single quotes are literal — nothing is expanded.
Single-quote any value containing a dollar sign.

Expansion applies to uppercase names only, and it does not care about double quotes:

  • PASSWORD=p$ASSW0RD and PASSWORD="p$ASSW0RD" both import as just p$ASSW0RD is an undefined variable and expands to nothing.
  • PASSWORD="p$assw0rd" survives intact, because $assw0rd is lowercase.

That asymmetry is the trap: a value works, one character becomes a capital, and it silently truncates. Single-quote anything containing a $ and stop thinking about it — PASSWORD='p$ASSW0RD'.

A - in a name (MY-KEY=x) is a parse error and fails the whole file.

dibbla secrets get

Print a secret’s value. Output is the raw value with no labels — pipeable.

FlagPurpose
<name> (positional, required)Secret name.
-d, --deployment <alias>Read a deployment-scoped secret.
$dibbla secrets get DATABASE_URL
postgres://user:[email protected]:30432/main?sslmode=require
 
# Use it in another command
$psql $(dibbla secrets get DATABASE_URL)

dibbla secrets delete

Remove a secret. Apps that reference it will lose the env var on their next start.

FlagPurpose
<name> (positional, required)Secret name.
-d, --deployment <alias>Delete a deployment-scoped secret.
-y, --yesSkip the confirmation prompt.
$dibbla secrets delete STRIPE_KEY --yes
🗑️ Attempting to delete secret 'STRIPE_KEY' (global)...
 
✅ Secret 'STRIPE_KEY' deleted

See also

  • dibbla dbdb create automatically creates a DATABASE_URL secret.
  • dibbla deploy — deployments inherit global and matching scoped secrets at runtime, and deploy --env-file seeds env vars from the same kind of file.
  • dibbla run — the same file-then-flags precedence, for pipeline steps.