Self-host secrets checklist
Required and optional credentials for published-images and Compose deploys.
Never commit .env, never paste secret values into issues/PRs, and never
overwrite an existing .env without an explicit backup and operator consent.
Published images: what the installer fills
bash install-images.sh (without a pre-existing .env) copies
.env.images.example and fills empty required keys with openssl:
| Key | Installer fill | Role |
|---|---|---|
POSTGRES_PASSWORD |
openssl rand -hex 16 |
Postgres owner password inside Compose (migrations) |
POSTGRES_APP_PASSWORD |
openssl rand -hex 16 |
Password of the app’s rakazo_app login, which row-level security applies to |
BETTER_AUTH_SECRET |
openssl rand -hex 32 |
Auth/session signing |
ENCRYPTION_KEY |
openssl rand -hex 32 |
Encrypts stored credentials at rest |
SCREEN_PROXY_SECRET |
openssl rand -hex 32 |
Signs short-lived /novnc/* screen capabilities |
SANDBOX_SUPERVISOR_TOKEN |
openssl rand -hex 32 |
API ↔ sandbox supervisor auth |
Re-runs preserve an existing .env (they do not rotate secrets); they only append
POSTGRES_APP_PASSWORD when an older .env lacks it. Empty
required keys still fail closed at Compose validate time
(${VAR:?Set … in .env}).
Manual generation (same shapes the installer uses):
openssl rand -hex 16 # POSTGRES_PASSWORD, POSTGRES_APP_PASSWORD
openssl rand -hex 32 # BETTER_AUTH_SECRET, ENCRYPTION_KEY, SCREEN_PROXY_SECRET, SANDBOX_SUPERVISOR_TOKEN
Source-checkout .env.example also requires POSTGRES_PASSWORD and
POSTGRES_APP_PASSWORD (same openssl rand -hex 16 shape) for
infra/compose/docker-compose.yml. Put them in host-side DATABASE_MIGRATION_URL
and DATABASE_URL when using the optional docker-compose.postgres-host.yml overlay. Keep the password URI-safe: Compose
interpolates it into DATABASE_URL the same way the images stack does. Hex from
openssl rand is safe; characters such as @ : / ? # % are not.
Existing source-checkout pgdata volumes keep the user, password, and database
from first init (often the former hardcoded orkbot / orkbot). Keep those
values in .env, or change them in place with ALTER ROLE / rename. Recreate
the volume only after a backup (or when the data is disposable);
docker compose down -v deletes all Postgres state.
Source-checkout .env.example asks for a 64-hex ENCRYPTION_KEY in
comments; published-images installer uses 32 bytes of hex (64 hex chars) via
openssl rand -hex 32. Prefer long independent random values either way.
Do not reuse one string across keys.
Distinctness rules
These must be independent random values (do not copy-paste the same secret into multiple keys):
BETTER_AUTH_SECRETENCRYPTION_KEYSCREEN_PROXY_SECRETSANDBOX_SUPERVISOR_TOKENORKBOT_UPDATER_TOKEN(only if the updater profile is enabled; ≥32 chars, also distinct from the four above)
Rotating ENCRYPTION_KEY after credentials were stored makes old ciphertext
unreadable. Keep the original key for an existing deployment unless you
intentionally wipe encrypted material.
ENCRYPTION_KEY also derives the default master key for chat, memory and file
encryption, so changing it also makes that content unreadable. To move content
off it, set ENCRYPTION_MASTER_KEYS and run the rotation in
content-encryption.md, which re-wraps the space keys
without stranding content. Keep ENCRYPTION_KEY unchanged afterwards: stored
credentials still depend on it.
With MASTER_KEY_PROVIDER=aws-kms, these and the other API and worker
secrets can be kept in .env wrapped by the key manager instead of in
plaintext (wrapped settings).
Optional keys (leave blank if unused)
From .env.images.example (images installer). Leave blank if unused:
| Key(s) | When needed |
|---|---|
OPENROUTER_API_KEY |
Deployment-wide OpenRouter models |
TYPESAFE_API_KEY |
Optional TypeSafe Jev Auto Review verifier (ORKBOT_AUTO_REVIEW_PROVIDER=jev) |
COMPOSIO_API_KEY |
Composio managed catalog |
E2B_API_KEY / DAYTONA_API_KEY / BOAT_API_KEY |
Remote computers when SANDBOX_PROVIDER is not docker |
EMAIL_PROVIDER / EMAIL_API_KEY / SMTP_URL / EMAIL_FROM |
Optional account email via Resend API or SMTP |
EXPO_ACCESS_TOKEN |
Mobile push when the Expo project enables enhanced push security |
| Messaging tokens (Slack, Telegram, …) | Only if you enable those surfaces |
Optional APNS_VOIP_KEY_ID, APNS_VOIP_TEAM_ID, and APNS_VOIP_PRIVATE_KEY enable
iOS VoIP ringing. Keep the .p8 contents in the secret manager.
Blank optional keys are normal for a minimal published-images boot. Pipedream
Connect keys appear only in source/Compose .env.example, not the images
example.
Operator workflow
bash install-images.sh --prepare-only # creates .env + fills empties
# inspect key NAMES only if debugging; never log values
bash install-images.sh # pull + up; preserves .env
curl -fsS http://127.0.0.1:3100/internal/health
If sandbox in /internal/health is "none" or the supervisor never becomes healthy,
check that SANDBOX_SUPERVISOR_TOKEN is set and non-empty for the Docker
computer path. A missing token is a setup failure, not an “optional tighten
later” item.
Recovery without reprinting secrets
- Lost UI password: use SMTP recovery if configured; otherwise operator
identity recovery is out of band (DB). Prefer not to rotate
BETTER_AUTH_SECRETcasually on a live deploy. - Lost
.env: from backup only. Recreating random secrets on a volume that still holds Postgres data will desynchronize passwords and encryption. - Moving hosts: copy
.envand volumes together; treat.envas secret material in transit.
Related
Optional credential storage
Stored credentials can use self-hosted Infisical while short-lived secrets stay encrypted in Postgres. See Infisical setup, migration, and rollback.