Keys, Secrets, and Cryptography Operations
Whoever holds your token-signing key can become any user. Keep signing keys in a KMS or HSM where they cannot be exported, rotate them on a schedule you have rehearsed, and never let a database dump contain enough to forge a token or verify a peppered hash.
Your key inventory
| Key | Purpose | Where it lives | Rotation |
|---|---|---|---|
| Token signing keys | Sign ID tokens, JWT access tokens, SAML responses | KMS or HSM, non-exportable | Scheduled (for example every 90 days) plus on demand |
| Password pepper | Post-hash HMAC or encryption (Chapter 4) | KMS or HSM | Versioned; new hashes use the new version, old ones upgrade at sign-in |
| Data encryption keys | Encrypt TOTP secrets and sensitive columns | Envelope encryption: data keys wrapped by a KMS key | Rotate the wrapping key; re-wrap data keys |
| Session and CSRF secrets | Sign cookies or CSRF tokens if you use signed values | Secrets manager | Overlapping rotation |
| TLS certificates | Transport | Certificate manager with automated renewal | Automated |
| SAML SP keys | Sign requests and decrypt assertions | KMS or secrets manager | Publish new metadata ahead of rotation |
| Client secrets you issue | Confidential OAuth clients | Stored hashed in your database | Customer-driven, with overlap |
Algorithms
- Token signatures: ES256 (ECDSA P-256) or EdDSA where your clients support it; RS256 for maximum compatibility. Publish only what you use.
- Symmetric encryption: AES-256-GCM with unique nonces, through a vetted library or the KMS itself.
- Randomness: the operating system's cryptographic generator only.
- FIPS environments: check which algorithms and modules your validation requires before you choose (EdDSA and Argon2id may not qualify).
Signing key rotation, step by step
- Generate the new key in the KMS. Publish its public half in your JWKS with a new
kid, but keep signing with the old key. - Wait longer than the maximum time clients cache your JWKS (for example 24 to 48 hours).
- Switch signing to the new key.
- Keep the old public key in the JWKS until every token signed with it has expired.
- Remove the old key. Log every step.
Rehearse an emergency rotation: if a signing key is compromised, you must publish a new key, stop accepting the old one immediately, and revoke all sessions and refresh tokens, accepting that every user signs in again. Write the runbook before you need it.
Secrets hygiene
- No secrets in source code, container images, or plain environment files.
- Short-lived workload credentials from your cloud's identity system instead of long-lived API keys.
- Separate keys per environment and per region. A staging compromise must not touch production.
- Alert on every KMS administrative action and on unusual signing volume.
Warning
Common mistakes
- Signing keys stored as PEM files in a config repository.
- No
kidin tokens, so rotation breaks every client at once. - One key across all regions and environments.
- Never practicing an emergency rotation.
Key takeaways
- Whoever holds your signing key can become any user; keep it non-exportable in a KMS or HSM.
- Rotate signing keys through the JWKS with a new kid, waiting out client caches.
- Rehearse an emergency rotation before you need it.
- Separate keys per environment and per region.