[AIGOR-418] Support multiple decode keys for signing key rotation - #12
Merged
Merged
Conversation
LARAVEL_JWT_DECODE_KEY now accepts a comma-separated list of keys. Tokens are verified against the keys in order, so new tokens are signed with the encode key (which must be first in the list) while previously issued tokens stay valid against the fallback keys. Whenever a token is verified by a fallback key, the package dispatches JwtDecodedUsingFallbackKey so the application can track how much traffic still relies on the old key before withdrawing it. Also adds a PHPUnit/Testbench test suite with a CI workflow, and ignores the unfixed low-severity firebase/php-jwt advisory that otherwise blocks fresh composer installs on composer 2.9+. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both workflows have been failing on the Setup PHP step since at least July (also on the laravel-13-support branch). Bump them to PHP 8.3 to match the tests workflow and drop --ignore-platform-reqs, which is no longer needed once the runtime satisfies the package constraints. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Stage 1 of the JWT signing secret rotation (AIGOR-418): the decode side now accepts multiple keys, so new tokens can be signed with a new secret while previously issued tokens keep verifying against the old one.
LARAVEL_JWT_DECODE_KEYaccepts a comma-separated list (safe separator: keys arebase64:..., no commas in the alphabet). A single key keeps working as before — fully backward compatible.JwtDecodertries the keys in order; the first key must match the encode key, the rest are fallbacks.JwtIssueris untouched.JwtDecodedUsingFallbackKeyevent (decodedJwt+ matched key index) is dispatched whenever a token verifies with a fallback key — listen to it to watch legacy-key traffic drain before withdrawing the old secret (stage 2).InvalidConfigExceptioninstead of silently failing auth.Chose ordered try-over-list instead of
kid-based resolution: all tokens already in the wild carry nokid, so the legacy fallback path is needed either way, and with 2–3 HS256 keys the extra verify attempt costs microseconds.Tests & infra
firebase/php-jwtadvisoryPKSA-y2cr-5h3j-g3ys(low severity, affects all 6.x, no fixed release exists): composer 2.9+ refuses to resolve the dependency otherwise, which would break fresh installs in all CI workflows since the lock file isn't committed.Rotation usage
Verification
🤖 Generated with Claude Code