Not every secret is an API key. Session signing keys, JWT signing secrets, HMAC keys and encryption keys have different consumers and different rotation consequences, but they share one requirement: full entropy from a cryptographically secure source. A secret someone typed is not a secret; it is a password with delusions.
Matching strength to purpose
| Secret | Recommended | Why |
|---|---|---|
| Session cookie signing | 256 bits | Rotating it logs every user out, so it lives a long time |
| JWT HS256 signing key | 256 bits | HMAC-SHA256 gains nothing above its 256-bit block size |
| HMAC webhook secret | 256 bits | Matches the hash output; longer keys are hashed down anyway |
| AES-256 key | 256 bits | Exactly 32 bytes, no more, no less |
| Encryption key wrapping | 256 bits | Protects everything below it |
The pattern is that 256 bits is almost always correct. Going higher is not wrong, but for HMAC it is genuinely pointless: keys longer than the hash's block size are hashed before use, so a 1024-bit HMAC key becomes a 256-bit one before it does any work.
Encoding for the consumer
Where the secret is going determines the encoding:
- Environment variables — Base64 or hex. Both survive shell quoting; avoid characters that need escaping.
- Kubernetes Secrets — plain, and let Kubernetes handle the Base64 in the
datafield. Double-encoding is a classic and confusing bug. - AES keys via Web Crypto — raw bytes, usually supplied as hex and parsed with a hex decoder.
- JWT signing — most libraries accept a UTF-8 string, so any printable encoding works. Be aware that a Base64 string used as a signing key is signed as its literal characters, not as the bytes it encodes.
Rotation is what makes a secret survivable
Every secret should have a rotation story before it is deployed, because the consequences vary sharply:
- Session signing key — rotating invalidates every session. Support two keys at once: sign with the new, accept either, retire the old after the session lifetime elapses.
- JWT signing key — rotating invalidates every issued token. Use a
kidheader from day one so you can publish two keys and roll without downtime. - Encryption key — rotating requires re-encrypting existing data. Use envelope encryption: a data key per record, wrapped by a master key, so rotating the master rewraps keys rather than rewriting data.
Frequently asked questions
Can I use this for an AES encryption key?
Yes. Choose 256 bits and hex encoding, which gives 64 hex characters — exactly what AES-256 needs. The AES encryption tool accepts that format directly under "raw hex key".
Why is 256 bits recommended everywhere rather than something larger?
Because for the algorithms in use, larger keys do not increase security. HMAC hashes oversized keys down to the block size. AES-256 is the largest AES key. The realistic threats to a secret are leakage and over-broad access, not brute force.
Should a session secret be different from a JWT signing key?
Yes. Separate secrets mean a compromise of one does not forge the other, and it lets you rotate on different schedules — which matters because their rotation costs are very different.
Is a Base64-encoded secret weaker than hex?
No. Both encode the same random bytes; Base64 is just denser. The one hazard is that some libraries treat the string as literal characters rather than decoding it, so be consistent about whether your secret is "these bytes" or "this string".