Custom OIDC providers (POST /admin/custom-providers) can only authenticate to the provider's token endpoint with a client_secret (client_secret_basic / client_secret_post). There is no way to use private_key_jwt (RFC 7523, OIDC Core §9).
Many regulated IdPs only accept asymmetric client authentication: healthcare and government identity providers, and anything following FAPI 2.0, which does not allow shared secrets. For those IdPs, the custom provider feature cannot be used at all.
Tested against supabase/gotrue:v2.196.0, with a mock OIDC provider whose token endpoint only accepts private_key_jwt:
token_endpoint_auth_methods_supported: ["private_key_jwt"], but that field is not kept in the stored discovery_document, and the admin API has no parameter to set the auth method./callback, GoTrue sends client_secret_basic, then retries with client_secret_post. It never sends client_assertion.oauth2: "invalid_client" "client authentication 'client_secret_post' not allowed; expected private_key_jwt"
500: Unable to exchange external code
A reference client using private_key_jwt against the same mock gets an ID token, so the mock itself works. The only external-side code path is oauth2.Config.Exchange in internal/api/provider/custom_oauth.go, which only sends the client secret. master (v2.198.0-rc.21) has no client_assertion handling for external providers either.
Add a token_endpoint_auth_method to custom providers (client_secret_basic | client_secret_post | private_key_jwt). For private_key_jwt:
client_secret) plus an optional kid.client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer and a client_assertion JWT: iss = sub = client_id, aud = token endpoint, short exp, unique jti.This is additive. Existing providers keep the default client_secret_basic.
Handle the OIDC login outside GoTrue, then create the GoTrue session through the admin API. That works, but it gives up the custom provider feature (claims allowlist, identity linking) for exactly the IdPs where it would help most.
The mock provider and a compose file that reproduces this are available if useful.
Axel Vanraes requests support for private_key_jwt client authentication in custom OIDC providers, as current options only allow client_secret methods. This is necessary for compliance with regulated identity providers that require asymmetric authentication. A proposal is made to add token_endpoint_auth_method support for private_key_jwt, including handling of JWT assertions. Warwick Hope supports this, highlighting its importance for Microsoft Entra ID users.
+1 from a Microsoft Entra ID user. Entra app registrations accept certificate credentials (private_key_jwt), and client secrets are capped at 24 months in the portal, so a missed renewal takes sign-in down for everyone. Please include the built-in Azure provider in this, not only custom OIDC providers. Longer term, support for Entra federated identity credentials (client_assertion from a workload identity token) would remove stored credentials entirely.