Skip to content

fix(sdk): preserve issuer identity byte-for-byte - #52

Open
RobertoIskandarani wants to merge 1 commit into
mainfrom
fix/preserve-issuer-identity
Open

fix(sdk): preserve issuer identity byte-for-byte#52
RobertoIskandarani wants to merge 1 commit into
mainfrom
fix/preserve-issuer-identity

Conversation

@RobertoIskandarani

Copy link
Copy Markdown
Contributor

An authorization server whose issuer identifier legitimately ends in / mints tokens whose iss carries that slash (RFC 9068). The SDK stripped the trailing slash from the configured issuer before storing it, then passed the stripped form to the token verifier as the expected iss — so every otherwise-valid token from such an AS was rejected, with no workaround short of misconfiguring the issuer.

Why both halves move together

RFC 8414 §3.3 requires the metadata issuer to be identical to the configured one, and §4 spells the comparison out as code-point-for-code-point with no normalization. Both sides of that check were stripped too (documentCache.ts), which masked the first defect during discovery: discovery passed, then verification failed. Fixing either alone moves the symptom rather than removing it.

What is deliberately unchanged

Deriving the .well-known URL still drops the terminating slash (RFC 8414 §3.1). That is derivation, not identity — buildMetadataUrl continues to do it, and the tests pinning that behaviour are untouched.

Changes

  • core/client.ts — store options.issuer verbatim.
  • core/fetching/documentCache.ts — keep expectedIssuer verbatim, and compare the raw metadata issuer for exact equality.

Tests

tests/core/issuerIdentity.test.ts covers both legs: a token whose iss carries the configured trailing slash verifies, and a metadata document whose issuer differs only by a trailing slash is rejected with MetadataFetchError.

Both were mutation-checked — reintroducing the strip in client.ts fails the first leg.

Full suite green: 384 / 42 / 38 / 40 / 124 across the five packages, plus lint and typecheck.

Migration

If your configured issuer differs from your authorization server's actual identifier by a trailing slash, correct the config. The SDK no longer reconciles them.

An authorization server whose issuer identifier legitimately ends in "/" mints
tokens whose `iss` carries that slash (RFC 9068). The SDK stripped the trailing
slash from the configured issuer before storing it, then passed the stripped
form to the token verifier as the expected `iss` — so every otherwise-valid
token from such an AS was rejected, with no workaround short of misconfiguring
the issuer.

RFC 8414 §3.3 requires the metadata `issuer` to be identical to the configured
one, and §4 spells the comparison out as code-point-for-code-point with no
normalization. Both sides of that check were being stripped too, which masked
the first defect during discovery: discovery passed, then verification failed.
They are fixed together because fixing either alone moves the symptom rather
than removing it.

Deriving the `.well-known` URL still drops the terminating slash (RFC 8414
§3.1). That is derivation, not identity, and is deliberately unchanged —
`buildMetadataUrl` continues to do it, and the tests pinning that behaviour
stay as they are.

Migration: if your configured issuer differs from your authorization server's
actual identifier by a trailing slash, correct the config. The SDK no longer
reconciles them.
@RobertoIskandarani
RobertoIskandarani requested a review from a team as a code owner August 6, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant