A secret variable holds a credential, such as an API key, a token or a password. Your app receives it as an ordinary environment variable, but once it is saved nobody can read the value back: not in the console, the HTTP API or the nimbus CLI. You can only replace it or delete it. Keep your own copy in a password manager.
Secret values are never stored in the platform's own database, and the audit log records which keys changed, never their values.
Plain and secret variables#
| Plain variable | Secret variable | |
|---|---|---|
| Console (Resources → Environment Variables) | Value shown | Masked, with a Secret badge |
GET /api/v1/apps/:id/env | value | "value": null, "secret": true |
nimbus env | Value shown | Masked |
nimbus env get KEY | The full value | Refused |
| Claude connector | Value, unless it looks like a credential | Masked |
| Delivered to web, workers, release command and one-off runs | Yes | Yes |
A key is either plain or secret, never both. Your code reads both kinds the same way, with no changes needed.
Adding and changing secrets#
On the app's Resources tab, under Environment Variables → Secrets:
- Add secret: enter a Key (such as
API_KEY) and a Value, then Save secret. - Replace value: set a new value for an existing key. The old value can't be recovered.
- Delete secret: removes the key from the app.
- Make a plain variable secret: in the environment editor, the lock icon next to a plain variable (Convert … to a write-only secret) moves its value into secrets. From then on it is write-only.
From the CLI, read the value from standard input so it doesn't end up in your shell history:
printf %s "$STRIPE_KEY" | nimbus env set STRIPE_KEY=- --secret
nimbus env unset STRIPE_KEY
The HTTP API sets, replaces or promotes a secret with PUT /api/v1/apps/:id/env/secrets/:key, and removes any variable with DELETE /api/v1/apps/:id/env/:key.
Database URLs and other managed secrets#
Dependencies inject their credentials as managed secrets: a managed database's DATABASE_URL and DATABASE_PASSWORD, a bucket's S3_SECRET_ACCESS_KEY, the AI gateway's API key. They show a Managed badge and can't be replaced or deleted by hand; rename or detach them from the dependency instead. A managed database's DATABASE_URL contains its password, so it is listed with no value. To see it, open the database's page under Storage → Databases and show the password.
When a change takes effect#
- On an app with running instances, saving or deleting a secret restarts the app (the console asks you to confirm first). On an app that has never been deployed, the change is picked up by the first deploy. Saving several secrets restarts once per secret.
- The restart is a new release, and the change is applied only once that release is healthy. The API answers with the release it created and an
appliesfield (nowornext_deploy). nimbus env setandnimbus env unsetfollow the restart and end withApplied: <app> is running with the change., or, if the new instances never became ready,Not applied: the restart failed (<reason>).with a non-zero exit while the previous release keeps serving.--no-waitreturns at once with the release ID.- A failed change is not rolled back: the value is saved, and the next change or deploy tries again.
Staging and preview environments#
An app's secrets belong to production only. Staging and preview environments never receive them. Each environment has its own secrets, set per environment (nimbus env set KEY=- --secret --env staging), and starts with a copy of the app's Defaults for other environments, such as test-mode API keys. You'll find that list, collapsed, inside the Secrets section. Changing a default later leaves existing environments as they are, and changing an environment's secret restarts only that environment.
Limits#
- Secrets are not for static sites. A static site has no runtime, so its variables are only available at build time, and anything the bundler inlines ships to the browser as public text.
- Secret values are hidden from the console, API and CLI, but your own app can read them. Anyone who can run commands in your app (for example with
nimbus run) can print them.
Also available as Markdown.