Site ↗
Documentation sections
Operations · 0.8.1

Rotating secrets and renewing certificates

Replace application keys, PostgreSQL passwords, S3 or registry access, and certificates without manually editing runtime files.

On this page

Use rotate-secrets to change secrets: the controller updates files and dependent components consistently. Plan a short service interruption.

Work from the project root: Source on the VPS as the deploy user, Archive/Registry on the controlling computer, and prod-local on your computer.

1. Choose the action

--kind Changes Preparation
auth Application token signing keys New values are created on the server; no JSON file needed
postgres Database password and related connection settings No new secrets file needed
media S3 image access keys media_access_key, media_secret_key, optional media_session_token
backup S3 backup access keys backup_access_key, backup_secret_key, optional backup_session_token
registry Docker image download access registry_username, registry_password
db-leaf PostgreSQL certificate signed by the current certificate authority (CA) No new secrets file needed
db-ca PostgreSQL certificate authority, trust, and certificate No new secrets file needed

Registry is available only for the current registry release; media and backup only for S3. These actions change access to the same storage rather than moving data.

First run status --env production --json and ensure no operation is active.

2A. Application keys, database password, or database certificates

These kinds do not require JSON with new values:

bash ./deploy/control rotate-secrets --env production \
  --kind auth --confirm production

Replace auth with postgres, db-leaf, or db-ca for another action. Users may need to sign in again after auth rotation.

2B. S3 or registry keys

Obtain new keys from the provider while leaving the old ones active. Create a file outside the repository:

umask 077
ROTATION_FILE="$HOME/admingen-media-rotation.json"
touch "$ROTATION_FILE"
chmod 600 "$ROTATION_FILE"
nano "$ROTATION_FILE"

For media, enter:

{
  "media_access_key": "NEW_ACCESS_KEY",
  "media_secret_key": "NEW_SECRET_KEY"
}

For backup, use instead:

{
  "backup_access_key": "NEW_ACCESS_KEY",
  "backup_secret_key": "NEW_SECRET_KEY"
}

For registry:

{
  "registry_username": "NEW_USERNAME",
  "registry_password": "NEW_TOKEN"
}

Choose just one of the three objects; add a session token if your provider requires it. Run the corresponding kind:

DEPLOY_SECRETS_FILE="$ROTATION_FILE" \
  bash ./deploy/control rotate-secrets --env production \
  --kind media --confirm production

Do not pass key values through command arguments or logs. After success, check the affected function: image upload, backup, or image access. Then revoke old keys and delete the temporary file if no longer needed.

Public HTTPS certificate

bash ./deploy/control certificates --env production --confirm production

This maintains Nginx/Certbot rather than PostgreSQL certificates. DNS and ACME access must work. Prod-local uses its own local CA; add it to trusted authorities on your computer.

If the operation is interrupted

bash ./deploy/control status --env production --json
bash ./deploy/control reconcile --env production --json

Normal resume does not support rotate-secrets. Use the journal to determine which values were already applied, then follow recovery instructions. Do not run a second rotation concurrently. Abandon does not restore old keys at the external provider.