Skip to content

Comments

feat: add use_oidc_discovery_issuer option for generic OIDC provider#4537

Open
getlarge wants to merge 4 commits intoory:masterfrom
getlarge:feat/use-oidc-discovery-issuer
Open

feat: add use_oidc_discovery_issuer option for generic OIDC provider#4537
getlarge wants to merge 4 commits intoory:masterfrom
getlarge:feat/use-oidc-discovery-issuer

Conversation

@getlarge
Copy link

@getlarge getlarge commented Feb 11, 2026

Related issue

Closes #4536

Changes

  1. selfservice/strategy/oidc/provider_config.go — add UseOIDCDiscoveryIssuer bool field
  2. selfservice/strategy/oidc/provider_generic_oidc.go — pre-fetch discovery document to get the real issuer, pass it to InsecureIssuerURLContext, then call NewProvider with the discovery URL
  3. embedx/config.schema.json — add use_oidc_discovery_issuer to provider schema
  4. selfservice/strategy/oidc/provider_generic_test.go — 3 unit test cases
  5. selfservice/strategy/oidc/strategy_test.go — 1 e2e test (full registration flow with Hydra and mismatched issuer)

Why pre-fetch the discovery document?

InsecureIssuerURLContext serves two purposes in go-oidc:

  1. Skip the discovery URL == issuer validation
  2. Store the passed value as the provider's issuer for ID token verification

If we naively pass the discovery URL (e.g. https://tenant.b2clogin.com/tenant.onmicrosoft.com/policy/v2.0), the provider stores that as its issuer. But the ID token's `iss` claim contains the real issuer from the discovery document (e.g. https://tenant.b2clogin.com/tenant-guid/v2.0/). Token verification then fails with "id token issued by a different provider".

So we first fetch the discovery document to extract the real issuer, pass that to InsecureIssuerURLContext, then let NewProvider do its normal discovery (which is a cache hit thanks to the ristretto cache in Ory's go-oidc fork).

Test plan

  • Unit tests: issuer mismatch rejected by default, accepted with flag, discovered endpoints used
  • E2e test: full OIDC registration flow with Hydra using mismatched issuer (localhost vs 127.0.0.1)
  • Manual: tested against real Azure AD B2C tenant with standard user flows

🤖 Generated with Claude Code

getlarge and others added 2 commits February 10, 2026 19:46
Allows the issuer returned by the OpenID Connect Discovery document to
differ from the issuer_url used to fetch it, using go-oidc's
InsecureIssuerURLContext.

This is required for providers like Azure AD B2C where the discovery URL
contains the policy name but the issuer in the discovery document and
tokens does not.

ID Token issuer validation still occurs — tokens are verified against
the issuer value from the discovery document. Only the OIDC Discovery
§4.3 requirement that the discovery URL must equal the issuer is relaxed.

Refs: ory#2404, ory#4005

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Without this, Kratos rejects the field at config validation time
since the schema has additionalProperties: false.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@getlarge getlarge requested review from a team and aeneasr as code owners February 11, 2026 08:23
@CLAassistant
Copy link

CLAassistant commented Feb 11, 2026

CLA assistant check
All committers have signed the CLA.

@getlarge
Copy link
Author

If you are open to this adjustment, I can add some automated e2e tests.

getlarge and others added 2 commits February 11, 2026 12:02
InsecureIssuerURLContext stores the passed value as the provider's
issuer for token verification. Previously we passed the discovery URL,
which caused ID token validation to fail when the token's iss claim
differed from the discovery URL.

Now we pre-fetch the discovery document to extract the real issuer
and pass that to InsecureIssuerURLContext, so token validation uses
the correct issuer value. The second fetch by go-oidc's NewProvider
is a cache hit (ristretto cache in Ory's go-oidc fork).

Also add an e2e test using Hydra that exercises the full registration
flow with a mismatched issuer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

feat: Add use_oidc_discovery_issuer option for generic OIDC provider (Azure AD B2C support)

2 participants