PASETO Key Rotation Strategy
Best practices for rotating PASETO signing and encryption keys, including kid hints, dual-acceptance windows, and revocation patterns.
Detailed Explanation
Key rotation in PASETO follows the same patterns as any other token format, but PASETO's footer + PASERK conventions make it cleaner to implement.
Why rotate:
Rotate signing/encryption keys regularly to limit the blast radius of a leaked or compromised key. Common rotation cadences: 90 days for high-value keys, 180-365 days for lower-traffic keys. Always rotate immediately on suspected compromise.
The basic rotation pattern:
- Generate the new key (e.g.
k4.publicandk4.secretfor v4.public). - Distribute the new public key (or wrapped symmetric key) to all verifiers; verifiers configure both the old and new keys, indexed by
kid. - Switch issuers to sign with the new key, putting the new
kidin every issued token's footer. - Wait at least
max(token-lifetime)so all outstanding tokens with the old kid expire. - Remove the old key from verifiers.
This is the dual-acceptance pattern: verifiers accept both keys during the overlap, but issuers only ever use one at a time.
Picking a kid format:
Use deterministic identifiers (PASERK k4.lid / k4.pid) rather than human-chosen names like "v2". Deterministic ids are collision-resistant and don't require coordination. If you must use human-friendly names (prod-2026-q1), enforce them in a registry to prevent collisions.
Revocation vs expiration:
PASETO doesn't have built-in revocation — once issued, a token is valid until exp. For revocation, you need either (1) very short exp values (e.g. 5-15 minutes for access tokens, paired with longer-lived refresh tokens), or (2) a server-side denylist of revoked jti values. Most production systems combine both: short-lived tokens + a denylist for the rare immediate-revoke case.
Local vs public rotation:
v*.local rotation is harder than v*.public because the symmetric key both issues and verifies. The good news: PASETO's local tokens are typically used within a single trust domain, so you can coordinate the cutover more tightly. The bad news: there's no public key to gradually distribute — every verifier needs the new symmetric key at once.
Use Case
A team rotates their v4.public signing key quarterly: each quarter's kid is the PASERK k4.pid of the new public key, and verifiers retain the previous quarter's key for one max-token-lifetime overlap window.