Dibbla Docs Get started Guides Workflows Changelog
Open Console
Guides

Environment & secrets

The scope model — global, per-deployment, per-service — what an env var is and what a write-only secret is, plus the platform variables you get for free and the ones you must not fight.

Rotate secrets and env vars covers the console side. This page is the model underneath it: where a value lives, and who sees it. Running the app on your own computer — with its settings, and development values of your own for its secrets — is Secrets and local development.

Three scopes

ScopeSet withWho gets it
Globaldibbla secrets set KEYevery app in the organisation
Deploymentdibbla secrets set KEY -d my-appone app, all its services
Servicedibbla secrets set KEY -d my-app --service apione service of one app

The narrowest scope that holds a value wins. Reach for global sparingly: it is right for something genuinely shared (a database every app queries) and wrong for anything an app owns.

# at your terminal — the CLI asks for the value and does not echo it
$dibbla secrets set STRIPE_KEY -d my-app
 
# or a link where the value is typed on a Dibbla page — what an AI assistant runs
$dibbla secrets request STRIPE_KEY -d my-app --title "Stripe secret key"
 
# a file of keys you wrote, in one go — kept outside the deploy directory
$dibbla secrets import ../secrets/.env.prod -d my-app
 
$dibbla secrets list
$dibbla secrets delete STRIPE_KEY -d my-app --yes
Leave the value out of the command

dibbla secrets set NAME -d app asks for the value at a hidden prompt — paste it, then press Enter on an empty line. A pipe or < file works too. A value typed as an argument still works, with a warning: it is now in your shell history, and in an AI assistant’s transcript if one ran the command.

Env vars and secrets

Two kinds of value reach your app’s environment, and the line between them is the rule:

  • An env var is not sensitive. It is stored as it is, shown in the console, returned by the API, and readable by anyone who can read the app’s configuration — including an AI assistant working on the app. deploy -e, apps update -e, --env-file and dibbla.yaml environment: set env vars, and they persist across updates. Use them for settings: a log level, a feature flag, a public URL.
  • A secret is write-only. Once it is saved, no Dibbla API, CLI command or MCP tool returns its value: the console shows a mask, dibbla env pull and dibbla export give the name only, and dibbla secrets get is gone. Dibbla hands it to the running app’s environment, and to nothing else. Use a secret for anything that grants access: an API key, a token, a password, a connection string.

Why write-only. Assistants do much of the work on an app now, and anything a platform hands an assistant can end up in its transcript, its client’s history or a provider’s logs. A value that no Dibbla API, CLI command or MCP tool returns cannot travel that way, whoever is asking — a person, a script or an assistant.

How a value gets in. From a person, never through an assistant:

  • in your own terminal, dibbla secrets set NAME -d my-app, pasted at a hidden prompt (or secrets import for a file of them);
  • on the console’s Secrets page;
  • through a link to a signed-in Dibbla page where you type it — dibbla secrets request in the CLI, or the platform connector’s request. That is how an assistant asks for a secret without ever seeing it: see Giving the assistant a secret without pasting it.

A secret cannot become an env var by the back door. Every env write is checked. An env var named like one of the app’s secrets is refused for everyone (ENV_SHADOWS_SECRET), because it would replace the secret at runtime. A name or value that looks like a secret is refused (ENV_LOOKS_LIKE_SECRET) unless a person confirms it is not one; an assistant never may. In dibbla.yaml, which is already in the app’s source, such an entry only warns a person — but an assistant’s deploy, or a proposal it wrote, is refused for it. The details are under env vars that look like secrets.

An env var that should have been a secret all along is promoted — with dibbla env promote, Make secret in the console’s environment editor, or by an assistant through the platform connector. Promotion asks for a new value, because the old one has been readable and counts as exposed: you rotate it where it was issued and enter the new one on a Dibbla page. On save the env var is removed from the whole app — a promotion is app-wide — and the app restarts.

Logs name a secret; they do not show it. If one of the app’s secret values turns up in its logs or build output — a connection string in a startup line, say — Dibbla shows [secret NAME] in its place. Values shorter than 8 characters are left alone, because they turn up in ordinary text. This protects against accidents, not against someone who can deploy the app and wants a value out: they can encode it any other way.

What the promise is. No Dibbla API, CLI command or MCP tool returns a secret’s value. That is not the same as “a secret cannot be extracted”: whoever can deploy the app can make it print its own environment.

Build time is not run time

Frontend bundlers inline variables at build time. A value you set after the build — including anything you add with apps update -e — will not appear in an already-built bundle, no matter how correct it looks in the console. If a browser needs a value, it has to be present when the image is built; if a server needs it, run time is fine.

What the platform injects

Your app receives a set of DIBBLA_* variables it did not set: its own alias, its service name, the LLM gateway URL, service-discovery addresses for its siblings. Two rules:

  • Do not try to set them. The platform filters DIBBLA_* in both directions — they never appear in the console’s editor and are dropped if you submit them.
  • Read them rather than hardcoding. The gateway URL and sibling addresses differ per environment; that is the entire point of them being injected.

The delete-by-omission rule

The console’s environment editor submits the whole set, so removing a row deletes that variable on save. Existing secret values come back as ****, and saving **** preserves them — which is what lets you change one variable without knowing the others. Deleting a masked row asks for confirmation, because the platform cannot show you what you are about to discard.

The CLI is explicit instead: secrets set adds or replaces one key, secrets delete removes one. Nothing is implied by omission.