Skip to content

fix: bind Microsoft native id_token issuer to its tid claim - #13

Merged
dmakarenko merged 1 commit into
goodnotesfrom
kratos-microsoft-verify-tid-issuer-20260930
Sep 30, 2026
Merged

dmakarenko merged 1 commit into
goodnotesfrom
kratos-microsoft-verify-tid-issuer-20260930

Conversation

@dmakarenko

Copy link
Copy Markdown
Collaborator

Native Microsoft Verify now checks iss against https://login.microsoftonline.com/<tid>/v2.0 built from a UUID tid, and pins microsoft_tenant when it is a UUID. common/organizations/consumers/domain names accept any tenant. The dead payload-kid lookup (fmt.Println, uncached http.Get) is deleted, and the JWKS fetch uses the registry HTTP client.

Why: the expected issuer came from the token itself, so the issuer check compared the token with itself and a configured tenant was never enforced. Production uses common, so valid v2 MSAL tokens are still accepted. v1 sts.windows.net tokens are now rejected.

Tested: TestMicrosoft* 19 pass / 0 fail on Go 1.26. The full selfservice/strategy/oidc package gives 145 pass / 3 fail, and the 3 failures are the Hydra tests that need Docker (the same as the baseline). An Opus review found no blockers.

https://claude.ai/code/session_0192dFsdvVuQdqMdVxi9HDkz

Native Verify took the expected issuer from the token's own iss claim, so
the issuer check compared the token with itself. A tenant set as
microsoft_tenant was never enforced, and tokens whose iss did not match tid
were accepted.

Verify now requires a UUID tid and checks iss against
https://login.microsoftonline.com/<tid>/v2.0, as the web flow does. A tenant
set as a UUID is pinned (400 on mismatch, and the reason does not show the configured tenant, because this check runs before the signature check). common, organizations, consumers
and domain names accept any tenant, so the production config (common) does
not change.

The unreachable payload-kid issuer lookup (fmt.Println, uncached http.Get
on the default client) is deleted. The JWKS fetch now uses the registry
HTTP client, because ClientContext is set before NewRemoteKeySet.

Claude-Session: https://claude.ai/code/session_0192dFsdvVuQdqMdVxi9HDkz
@dmakarenko
dmakarenko force-pushed the kratos-microsoft-verify-tid-issuer-20260930 branch from b940ea5 to b885291 Compare September 30, 2026 20:26
@dmakarenko
dmakarenko merged commit c3dfe9e into goodnotes Sep 30, 2026
2 checks passed
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