VOD Docs

Secrets

Every secret in production, what it protects, where it lives and how to rotate it. Names only, never values.

All backend secrets live in one file on the server, ~/vod-app/infra/prod.env, which is git-ignored and never leaves the server. Frontend values live in the Vercel project settings. Nothing secret is committed to the repository.

Architecture diagram · placeholder
Secret flow: prod.env → which containers read each secret

Matrix of secrets × containers (api, worker, postgres, redis, minio, tusd).

Inventory

SecretProtectsRead by
POSTGRES_PASSWORD (inside DATABASE_URL_SYNC / DATABASE_URL)The databasepostgres, api, worker
REDIS_PASSWORDRedis: Celery queue, processing lock, upload slotsredis, api, worker
MINIO_ROOT_USER / MINIO_ROOT_PASSWORDMinIO administratorminio
minio_access_key / minio_secret_keyS3 access used by the backend and tusdapi, worker, tusd
jwt_secret_keySigning of every access and refresh tokenapi, worker
tus_hook_shared_secrettusd → API hook callsapi, tusd
RESEND_API_KEYSending email as the platformapi, worker
PGADMIN_DEFAULT_PASSWORDpgAdmin (local development only)— in production
Vercel: NEXT_PUBLIC_API_URLNot secret (public in the bundle)frontend build

NEXT_PUBLIC_* values are compiled into JavaScript that every visitor downloads, so they must never contain anything secret.

Rules

  • Generate values with a password manager or openssl rand -base64 48.
  • Never reuse the defaults from .env.example or docker-compose.local.yml.
  • Never paste prod.env into chats, issues or screenshots. Share variable names when asking for help.
  • Keep an offline copy of prod.env in a password manager; it is not backed up anywhere else.

Rotation

Edit the value in prod.env, then restart the containers that read it. Some secrets also need a change inside the service itself.

dc up -d --force-recreate api worker

Every existing access and refresh token becomes invalid immediately, so all users are signed out. Use this as the emergency response to a suspected key leak.

After a suspected leak

  1. Rotate the leaked secret (JWT key first if unsure: it signs everyone out).
  2. Check dc logs api for unusual admin activity around the time of the leak.
  3. Review recently created users and admins:
SELECT email, role, created_at FROM users ORDER BY created_at DESC LIMIT 20;

On this page