Olympus Docs
CookbookSecrets & encryption

Rotate secrets

Periodic rotation of Olympus secrets

Olympus has several secrets that should be rotated periodically. Rotation cadence depends on your threat model, but a sensible baseline:

SecretCadenceDifficulty
Database passwords90 daysMedium
Kratos session cookie key180 daysEasy (overlap supported)
Kratos cipher keyPer ADR 0006Hard (data re-encryption)
Hydra system secret90 daysEasy (overlap supported)
OAuth2 client secretsPer client needMedium
Encryption keySee encryption-key-rotationHard
TLS certsAuto (Caddy)None

Database passwords

Postgres passwords for kratos, hydra, athena users.

  1. Generate new password:
    openssl rand -base64 32
  2. Add to Postgres:
    ALTER USER kratos PASSWORD 'NEW_PASS';
  3. Update .env:
    KRATOS_DB_PASSWORD=NEW_PASS
  4. Restart container:
    podman-compose restart ciam-kratos

If you don't want downtime, use Postgres MD5 rotation (less ideal) or have two users with overlap.

This signs the ory_kratos_session cookie. Rotating invalidates existing sessions (users re-login) unless overlapped.

Kratos supports an array, the first key is used to sign, all are tried for verify.

# kratos.yml
secrets:
  cookie:
    - NEW_KEY
    - OLD_KEY

After 24h (longest session), drop OLD_KEY.

Hydra system secret

Hydra's system secret encrypts client secrets, etc., in DB.

# hydra.yml
secrets:
  system:
    - NEW
    - OLD
  cookie:
    - NEW
    - OLD

Same overlap pattern.

OAuth2 client secrets

For your apps. Rotate when:

  • A team member leaves who had access.
  • You suspect leakage.
  • Periodically (180d?).
# Add new secret without removing old (Hydra supports both during transition)
hydra update client <id> --secret NEW_SECRET --keep-old-secret
# Roll your app to use NEW_SECRET
# Then:
hydra update client <id> --secret NEW_SECRET  # removes old

Encryption keys

See Cookbook, Rotate encryption key, this is the most operationally complex rotation.

TLS certs

Caddy auto-renews. Nothing to do.

For pinned certs (rare), manual replacement.

Automation

Scripted rotation:

#!/bin/bash
# rotate-cookie-secret.sh
NEW_KEY=$(openssl rand -base64 32)
OLD_KEY=$(grep KRATOS_SECRETS_COOKIE .env | cut -d= -f2)

cat > .env.new << EOF
KRATOS_SECRETS_COOKIE=${NEW_KEY},${OLD_KEY}
EOF

cp .env.new .env
podman-compose restart ciam-kratos

# Schedule a cleanup in 24h
at "now + 1 day" << EOF
sed -i 's/,${OLD_KEY}//' /path/to/.env
podman-compose restart ciam-kratos
EOF

Inventory

Keep a secrets register: name, vault path, last rotated, next due. Update on each rotation.

# secrets-register.yml
secrets:
  - name: kratos_cookie
    vault: secret/olympus/kratos/cookie
    last_rotated: 2026-02-15
    next_due: 2026-08-15
    rotation_runbook: docs/cookbook/secrets-rotation.mdx#kratos-session-cookie-key

What NOT to rotate

  • Identity user passwords (users do that themselves).
  • OAuth2 access tokens (short-lived; rotation via refresh).
  • ID tokens (they expire).
  • Refresh tokens (one-shot rotation on use).

These rotate organically.

On this page