Secrets
Database passwords, API keys, tokens — sensitive values that shouldn’t live in your manifest or .env files. Banyan encrypts them at rest and injects them into containers at runtime.
Create a secret
banyan-cli secret create DB_PASSWORDEnter secret value: ********Secret "DB_PASSWORD" created.The value is encrypted with AES-256-GCM and stored in etcd. It never appears in your manifest, your deploy logs, or your task records.
You can also provide the value non-interactively:
# From a file (good for CI/CD)banyan-cli secret create DB_PASSWORD --from-file ./password.txt
# Inline (visible in shell history — use for testing only)banyan-cli secret create DB_PASSWORD --value "s3cret"Creating a secret that already exists updates its value.
Reference secrets in your manifest
Add a secrets: list to any service. Each secret name becomes an environment variable inside the container:
name: my-app
services: api: image: myapp/api:latest environment: - DB_HOST=db.my-app.internal secrets: - DB_PASSWORD - API_KEY ports: - "8080:8080"
db: image: postgres:15 secrets: - DB_PASSWORD environment: - POSTGRES_USER=banyanBoth api and db receive DB_PASSWORD as an environment variable. The api service also gets API_KEY. Regular environment: variables work alongside secrets.
Deploy as usual:
banyan-cli up -f banyan.yamlIf a secret doesn’t exist, the deploy fails immediately with a clear message:
Error: service "api" references secret "API_KEY" which does not exist.Create it with: banyan-cli secret create API_KEYManage secrets
List all secrets
banyan-cli secret listNAME CREATED UPDATED------------------------------------------------------------------------API_KEY 2h ago 2h agoDB_PASSWORD 5d ago 1h agoREDIS_AUTH 5d ago 5d agoView secret metadata
banyan-cli secret get DB_PASSWORDSecret: DB_PASSWORD Created: 2026-03-27T10:00:00Z Updated: 2026-03-27T15:30:00ZTo see the actual value (for debugging):
banyan-cli secret get DB_PASSWORD --revealSecret: DB_PASSWORD Created: 2026-03-27T10:00:00Z Updated: 2026-03-27T15:30:00Z Value: s3cret-passw0rdThe --reveal flag prevents accidental exposure in shared terminals or screen recordings.
Update a secret
Run create again with the same name — the value is replaced:
banyan-cli secret create DB_PASSWORDEnter secret value: ********Secret "DB_PASSWORD" created.Running containers keep the old value until you redeploy:
banyan-cli up -f banyan.yamlDelete a secret
banyan-cli secret delete DB_PASSWORDSecret "DB_PASSWORD" deleted.If a running deployment references the secret, the delete is blocked:
Error: cannot delete secret "DB_PASSWORD": referenced by deployment "my-app" (service: api)Tear down the deployment first, or update the manifest to remove the reference.
How it works
What’s encrypted
Secret values are encrypted with AES-256-GCM before being stored in etcd. During banyan-engine init, the wizard asks whether to generate a new encryption key or provide an existing one. The key is stored at /etc/banyan/keys/secrets.key on the engine.
How secrets reach containers
- You create a secret — the value is encrypted and stored in etcd at
/banyan/secrets/<name>. - You deploy with
secrets: [DB_PASSWORD]— the engine stores only the name in the task record. The plaintext value is never written to the task record. - When an agent polls for tasks, the engine decrypts the secrets just-in-time and includes them in the gRPC response.
- The agent injects each secret as an environment variable when starting the container.
All gRPC traffic travels over the WireGuard tunnel, so secrets are encrypted both at rest (etcd) and in transit (WireGuard).
Naming rules
Secret names must be valid environment variable identifiers: letters, digits, and underscores, starting with a letter or underscore. Uppercase is conventional but not enforced.
DB_PASSWORD ✓API_KEY ✓my_token_123 ✓3rd-party ✗ (starts with digit, contains dash)Secret vs environment collision
If a secret has the same name as an environment: variable, the secret takes precedence. This lets you migrate from plaintext env vars to secrets without changing your application code.
High availability
In a multi-engine setup, all engines must use the same secrets.key. The banyan-engine init wizard handles this:
-
First engine: Choose “Generate new key”. Copy the key file to the other engine nodes:
Terminal window scp engine-1:/etc/banyan/keys/secrets.key engine-2:/etc/banyan/keys/secrets.key -
Additional engines: Choose “Provide existing key file” and enter the path to the copied key.
Secrets are stored in the shared etcd cluster, so any engine can create, read, or delete them once the key is in place.
Limitations
- Environment variables only — secrets are injected as
-eflags, not mounted as files. File-based injection (for certificates, service account JSON files) is planned. - No automatic rotation — updating a secret requires a redeploy for running containers to pick up the new value.
- Cluster-wide scope — all secrets are available to all deployments. Per-deployment scoping is not yet supported.
- No external backends — secrets are stored in Banyan’s etcd. Integration with Vault, AWS Secrets Manager, or similar tools is planned.
See the Manifest Reference — Secrets for the full field reference and the CLI Reference — secret for all command options.