fixed: gave access and refresh tokens distinct JWT header types #10
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "token-types"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Every token had the header type
JWT, and refresh-token claims include every field an access token requires. So a refresh token, and therefore an authorization code, decoded as an access token. A refresh token that had been rotated or revoked at logout could still be used as a bearer token at/userinfo(with theidentityscope) and at its own app for the rest of its lifetime, 72 hours by default. It carried no capabilities, but it still identified the user.Access tokens now use the header type
at+jwt(RFC 9068) and refresh tokensrt+jwt.decodeTokenrequires the expected type. Authorization codes are still refresh tokens and share their type.Breaking: integrations need the updated
pkg/tokens/pkg/client. Tokens issued with the old header won't decode, so existing sessions must sign in again.Tests:
TestToken_TypesAreNotInterchangeable(both directions, server and client validators) andTestGetUserInfo_RejectsRefreshTokenAndAuthorizationCode. The service test fails onmain: userinfo accepts both.pkg/tokenscalled helpers whose signatures now take a token type.TestVerifyHeadernow expects plainJWTand the other token's type to be rejected.TestDecode_RejectsAudienceThatIsNotOneValueused to decode one token as both types. It now signs one token of each type with the same claims and checks the same audience errors.🤖 Generated with Claude Code