Secrets
A secret stores a single sensitive value — a database password, an API key, a signing token, an OAuth client secret — that your container needs at runtime but should never appear in logs, source code, or your container image.
A secret stores a single sensitive value — a database password, an API key, a signing token, an OAuth client secret — that your container needs at runtime but should never appear in logs, source code, or your container image.
Fields
| Field | Description |
|---|---|
| Handle | Unique identifier within the organisation (e.g. db-password). The handle drives the environment-variable name when the secret is injected into a container. Immutable once created. |
| Name | Display name shown in the console. |
| Value | The sensitive value to store. Encrypted on submission; never displayed again. |
How values are stored
Secret values are encrypted before they ever land on disk. The console and API surface metadata only — handle, name, version count, attached projects — never the value. The plaintext is materialised only at deployment time, inside the isolated environment that prepares the container's runtime environment, and discarded immediately after.
Versioning and rotation
Secrets are versioned. The first value you save is v1. Rotating creates v2 with the new value and marks it current — older versions are retained for rollback.
Rotation is the right tool whenever you:
- Rotate a credential on a schedule
- Replace a compromised value
- Cycle a third-party token
After rotation, containers that inject the secret pick up the new value on their next deploy. If the rotation breaks something, activate a previous version to roll back instantly — no need to re-enter the old value by hand.
Attaching to a project
Secrets live at the organisation level so multiple projects can share them when appropriate. A project can only use a secret that has been attached to it. Two-step model: create at the org, attach to the project, then wire to the container.
Attach a secret from:
- The console — Project → Attachments → Secrets
- Reis CLI —
reis project:attach <project-id> secrets <handle> - Terraform —
bahriya_project_secret_attachment - The API —
POST /organisations/{org}/projects/{project}/attach/secrets/{handle}
Detach reverses the operation; the API rejects detach if any running container in the project still injects the secret.
Wiring to a container as an environment variable
On a container, the secretsenvvar list maps each attached secret to the environment-variable name the application reads. The mapping is explicit — you choose the variable name, the platform supplies the decrypted value.
kind: container
type: http
handle: my-api
image: my-org/my-api:1.4.0
project: prod
regions:
- falkenstein-1
workload:
port: 8080
secrets:
- envvar: DATABASE_PASSWORD
secret: db-password
- envvar: STRIPE_KEY
secret: stripe-live-keyEach entry says: "find the secret with this handle attached to this project, decrypt it at deploy time, and expose the plaintext as this environment variable inside the container."
A single secret can be wired into any number of containers in the project, and the same container can wire a secret under more than one variable name if it needs to.
Reading the value from your application
The variable appears as a normal environment variable. Your application reads it using the language's standard API:
import os
db_password = os.environ['DATABASE_PASSWORD']const dbPassword = process.env.DATABASE_PASSWORD;dbPassword := os.Getenv("DATABASE_PASSWORD")There is no SDK to integrate, no network call to make, no extra dependency.
Secrets vs plain environment variables
| Secrets | Plain env vars | |
|---|---|---|
| Encrypted at rest | Yes | No |
| Visible in the console | No (value hidden) | Yes |
| Versioned with rollback | Yes | No |
| Scope | Organisation-level, attached per project | Per container |
| Use for | Passwords, tokens, keys, anything sensitive | Config flags, URLs, log levels |
Use a secret for anything you wouldn't want visible in a log line, an exported manifest, or your source control. Use plain environment variables for non-sensitive runtime configuration.
If both a plain environment variable and a wired secret target the same variable name, the secret wins.
Updating a value
To change a secret's value, rotate the secret. The change takes effect on the next deployment of every container that wires it. To force the new value into a running container immediately, redeploy from the container detail page.
The legacy update flow that overwrote the value in place is gone — every change goes through rotation so the previous value remains available for rollback.
Deleting a secret
Deleting a secret removes the value and detaches it from every project it was attached to. Containers that still wire the variable will fail to start on next deployment, so unwire the secret from all containers (and detach from every project) before deleting.
The handle is permanently consumed once used — even after deletion, you cannot create a new secret with the same handle.
Pricing
Secrets are billed at $0.01 per month while they exist in the organisation, plus $0.01 per region per month while attached to a project.