Skip to content

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

Merged
m0tzy merged 2 commits into
mainfrom
fix/cookie-session-user-token-family
Nov 4, 2026
Merged

m0tzy merged 2 commits into
mainfrom
fix/cookie-session-user-token-family

Conversation

@m0tzy

@m0tzy m0tzy commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Description

Session cookie validation now applies the same access-token claim checks as verifyAccessToken().

Previously CookieSession.authenticate() and authenticateWithSessionCookie() verified only the JWT signature, expiry and issuer. Both now call verifyAccessToken(), which also runs hasRequiredAccessTokenClaims:

  • sid and auth_time must be present.
  • sub_profile must be absent or user.
  • sub_type must be absent.

A cookie whose access token fails those checks returns invalid_jwt. CookieSession also drops its duplicate jwtVerify call.

Other behavior changes in CookieSession, which now match verifyAccessToken():

  • A token signed by a key that isn't in the JWKS now returns invalid_jwt instead of throwing. The same applies to a missing kid while multiple keys are active, and to an unsupported alg.
  • When no client ID is configured, the error message is now Must provide clientId to initialize JWKS.

New specs cover CookieSession.authenticate() and authenticateWithSessionCookie() when the cookie's access token has sub_profile: ai_agent or sub_type: authkit. Existing specs that mocked jwtVerify with an empty payload now mock it with a user access token payload.

Documentation

Does this require changes to the WorkOS Docs? E.g. the API Reference or code snippets need updates.

[ ] No

If yes, link a related docs PR and add a docs maintainer as a reviewer. Their approval is required.

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

@m0tzy
m0tzy requested review from a team as code owners November 4, 2026 21:13
@m0tzy
m0tzy requested a review from imkesin November 4, 2026 21:13
@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

[Medium impact] The PR appears safe to merge.

Summary

Both cookie authentication methods now call verifyAccessToken and read its verified claims.

  • Session cookies now accept only verified user access tokens.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Cookie authentication] --> B[Open sealed cookie]
  B --> C[verifyAccessToken]
  C --> D[Check signature, expiry and configured issuer]
  D --> E[Check required user claims]
  E -->|Pass| F[Return verified session fields]
  E -->|Fail| G[Return invalid_jwt]
Loading

Reviews (2) · Last reviewed commit: "refactor(user-management): Read session ..." · Reviewed by Greptile

CookieSession.authenticate and authenticateWithSessionCookie now validate
the cookie's access token with verifyAccessToken, so they apply the same
access token claim checks (hasRequiredAccessTokenClaims) as direct
verification instead of only checking signature, expiry and issuer.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration
devin-ai-integration Bot force-pushed the fix/cookie-session-user-token-family branch from 9b439d9 to 86e3cd1 Compare November 4, 2026 21:30

@imkesin imkesin 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.

Beautiful reduction in LOC (at least across non-test files)

Comment thread src/user-management/user-management.ts Resolved
…ed payload

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 fab1ea5 into main Nov 4, 2026
9 checks passed
@m0tzy
m0tzy deleted the fix/cookie-session-user-token-family branch November 4, 2026 22:55
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