Skip to content

fix(backend): Fix JWT array audience validation#8470

Open
jescalan wants to merge 1 commit intomainfrom
codex/fix-verify-token-array-aud
Open

fix(backend): Fix JWT array audience validation#8470
jescalan wants to merge 1 commit intomainfrom
codex/fix-verify-token-array-aud

Conversation

@jescalan
Copy link
Copy Markdown
Contributor

@jescalan jescalan commented May 4, 2026

Summary

This fixes JWT audience validation for tokens whose aud claim is an array.

verifyJwt now passes the raw aud claim and configured audience option into assertAudienceClaim. The assertion helper already normalizes string and string-array inputs, so this lets it evaluate array audiences correctly.

Scope

This does not mean default Clerk session tokens have an aud claim. They generally do not, and this PR does not change the existing behavior for tokens with no aud: if the token has no audience claim, verifyJwt still skips audience validation.

The bug only applies when both of these are true:

  • the caller configured audience
  • the token payload contains aud as a string array

That shape is valid JWT syntax and is already represented in this package's M2M token parsing fallback (aud?: string[]). Clerk-issued M2M tokens also allow custom claims, and aud is not reserved there. So the fix is scoped to correctly enforcing the existing audience option when an array aud is present, not to introducing audience binding for all Clerk tokens.

Root Cause

verifyJwt wrapped both values before calling the assertion:

assertAudienceClaim([aud], [audience]);

When the token already had aud as a string array, the assertion received a nested array. That shape skipped both validation branches: it was not a string, and it was not an array of strings. The function returned without enforcing the configured audience.

Tests

  • Added assertion coverage for two string arrays with no intersection.
  • Added verifier coverage using signed JWTs:
    • accepts an array aud when it includes the configured audience
    • rejects an array aud when it does not include the configured audience

Validation

  • NODE_OPTIONS=--no-experimental-webstorage pnpm --filter @clerk/backend build
  • pnpm --filter @clerk/backend build:runtime
  • NODE_OPTIONS=--no-experimental-webstorage pnpm exec vitest run src/jwt/__tests__/assertions.test.ts src/jwt/__tests__/verifyJwt.test.ts --environment node --typecheck.enabled=false
  • pnpm --filter @clerk/backend format:check
  • git diff --check

@vercel
Copy link
Copy Markdown

vercel Bot commented May 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment May 4, 2026 7:11pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 4, 2026

⚠️ No Changeset found

Latest commit: f2af9ba

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@jescalan jescalan changed the title [codex] Fix JWT array audience validation fix(backend): Fix JWT array audience validation May 4, 2026
@jescalan jescalan requested review from brkalow, dominic-clerk and jacekradko and removed request for brkalow May 4, 2026 19:18
@jescalan jescalan marked this pull request as ready for review May 4, 2026 19:18
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

📝 Walkthrough

Walkthrough

The pull request modifies JWT audience claim validation to handle array-type aud claims. A test case was added to assertAudienceClaim to verify error handling when audience arrays have no intersection. The production code in verifyJwt.ts was updated to pass the aud and audience values directly to assertAudienceClaim instead of wrapping them in single-element arrays. Two corresponding test cases were added to verify that JWT tokens with array aud claims are correctly accepted when the configured audience is present and rejected when absent.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(backend): Fix JWT array audience validation' directly summarizes the main change: fixing JWT validation when the audience claim is an array.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description clearly explains the JWT audience validation bug fix, including the root cause, the changes made, the scope limitations, and comprehensive test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant