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
| Scope | Set with | Who gets it |
|---|---|---|
| Global | dibbla secrets set KEY | every app in the organisation |
| Deployment | dibbla secrets set KEY -d my-app | one app, all its services |
| Service | dibbla secrets set KEY -d my-app --service api | one 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
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-fileanddibbla.yamlenvironment: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 pullanddibbla exportgive the name only, anddibbla secrets getis 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 (orsecrets importfor 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 requestin 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.
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.