Skip to content

fix(session): Reject non-user access tokens in session cookies - #70

Merged
m0tzy merged 2 commits into
mainfrom
fix/session-user-access-token-claims
Nov 5, 2026
Merged

m0tzy merged 2 commits into
mainfrom
fix/session-user-access-token-claims

Conversation

@m0tzy

@m0tzy m0tzy commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Summary

AuthKitCore.verifyToken, which validateAndRefresh uses, only ran jwtVerify (signature, exp, and iss when configured). It didn't check that the token was a user session access token, so other token types signed by the same environment key were accepted as a session.

const { payload } = await jwtVerify(token, this.getPublicKey(), issuer ? { issuer } : undefined);
return isUserAccessTokenPayload(payload);
// typeof sid === 'string' && typeof auth_time === 'number'
// && (sub_profile === undefined || sub_profile === 'user') && sub_type === undefined

This matches hasRequiredAccessTokenClaims in @workos-inc/node. sub_profile is optional on user access tokens, so a missing claim is still accepted. Adapters built on authkit-session pick this up when they upgrade.

TokenManager.verifyToken has the same plain jwtVerify, but nothing in src uses it outside its own spec, so this PR leaves it alone.

Tests: AuthKitCore.verifyToken() token claims in AuthKitCore.issuer.spec.ts covers sub_profile: ai_agent, sub_type: authkit, a missing or string auth_time, and a missing or numeric sid, plus sub_profile: user as the positive case. All 6 rejection cases fail without the AuthKitCore.ts change. The spec's default mocked payload now carries sid/auth_time.

Link to Devin session: https://app.devin.ai/sessions/7e123fc2545a49c282b043a4abd58f70
Open in Devin Desktop: https://app.devin.ai/desktop/session/7e123fc2545a49c282b043a4abd58f70?variant=devin
Requested by: @m0tzy

AuthKitCore.verifyToken now requires sid and auth_time, a sub_profile that is
absent or user, and no sub_type, so other token types signed by the same
environment key do not authenticate a session.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

Original prompt from madison.packer

What's the fix here? https://linear.app/workos/issue/VULN-4839/lt-app26-10-user-vs-agent-jwt-type-confusion

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Devin Review

🟢 Devin Review found nothing to fix · View findings

@greptile-apps

greptile-apps Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Critical impact] This PR appears safe to merge.

Summary

AuthKitCore.verifyToken now checks that signed tokens have user-session claims.

  • Session checks accept only user access tokens.

No new actionable issues were found. Tests were not run during this review.

Reviews (2) · Last reviewed commit: "test: Authenticate again with the refres..." · Reviewed by Greptile

Comment thread src/core/AuthKitCore.issuer.spec.ts Resolved
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

@greptileai review

@m0tzy
m0tzy merged commit e484381 into main Nov 5, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants