Secrets & Configuration
Your app’s configuration comes in two forms:
- Environment variables — plain
KEY=VALUEpairs set on an app (a Web Application or Background Worker) or inherited from its Environment or Organization. Use them for non-sensitive settings: feature flags, log levels, public URLs. - Secrets — encrypted values (API keys, passwords, tokens) stored by the platform and injected into apps by reference. Secret values are write-only: once saved, nobody can read them back through the dashboard or the API — you can only replace them.
Both reach your code the same way: as environment variables in the running instance. The difference is how they are stored and who can see them.
Environment variables
Plain configuration inherits from Organization → Environment → app, with the more specific value winning. There is no Project-level plain-variable scope. For example, an app’s LOG_LEVEL=info overrides its Environment’s LOG_LEVEL=debug; removing the app value restores inheritance.
Inherited values never override automatic public URL variables or variables supplied by attachments. An app may explicitly override PAAS_PUBLIC_URL and PAAS_PUBLIC_HOST; avoid reusing attachment variable names for unrelated settings. The platform sets PORT from the app’s port setting.
Use the Environment Variables guide for dashboard and CLI commands, key rules, automatic variables, and permissions. Plain values are visible to people with access to that scope; credentials belong in secrets.
Runtime variables configure the running app. Buildpack settings configure image construction; see runtime selection and static frontend builds. Browser assets expose any values compiled into them; see Designing Apps for d2o.
Secrets
Secrets store encrypted, write-only values. Their names start with an uppercase letter, followed by uppercase letters, digits, or underscores, don’t end with an underscore, and are at most 253 characters. A few endings (_S3, _REDIS_CONN, _MONGODB_PASSWORD, _MARIADB_PASSWORD) are reserved for credentials the platform creates. An app variable key also starts with an uppercase letter, and need not match the secret name.
For example, an app variable PAYMENT_KEY may reference a secret named STRIPE_PAYMENT_KEY. The value reaches the process as PAYMENT_KEY. See Managing Secrets for creation, permissions, rotation, and deletion.
Secret scopes
Secrets live at one of three levels, matching the platform hierarchy:
- Organization — for values shared across the whole organization.
- Project — for values shared by a project’s environments.
- Environment — for values specific to one environment, such as
productioncredentials that staging must never see. This is the most common scope, managed from the environment’s Secrets page.
Choose the narrowest scope that works. A production database password belongs
on the production environment, not on the organization.
How a secret reaches your app
A secret reaches an app only through a variable referencing it. The platform resolves the secret name from the nearest scope: Environment → Project → Organization. Creating a reference fails if no visible secret exists. Your code then reads an ordinary environment variable; it needs no platform SDK.
The binding instructions show both interfaces. Binding or rotating a secret rolls out new instances automatically; deleting and re-creating a referenced secret can require a manual restart. The authoritative timing rules are in When changes reach your app.
Next steps
- Environment Variables — the full guide to per-app configuration
- Managing Secrets — step-by-step secret creation and rotation
- Attaching a Database — connection strings injected for you
- Access Control — who can manage secrets