Mutual TLS Client Authentication
ProAuth supports OAuth 2.0 Mutual-TLS Client Authentication and certificate-bound access tokens according to RFC 8705. mTLS client authentication can be used at all ProAuth OAuth endpoints that require client authentication: token, introspection, revocation, device authorization, and pushed authorization request (PAR).
mTLS client authentication and certificate-bound access tokens satisfy the sender-constrained-token requirement for FAPI 2.0 Security Profile.
Configure the method per client application with tokenEndpointAuthMethod:
tls_client_authself_signed_tls_client_auth
When RequireCertificateBoundAccessTokens is enabled, access tokens issued by the token endpoint include a cnf claim with the SHA-256 thumbprint of the presented client certificate. This is enabled by default for mTLS client authentication methods and disabled by default for other methods.
Use the v2 Management API resource api/management/v2/ClientAppAuthenticationConfiguration to create or update this configuration. The request body uses these fields:
| Field | Description |
|---|---|
clientAppId | Client application id that owns the authentication configuration. |
tokenEndpointAuthMethod | Authentication method. Use tls_client_auth or self_signed_tls_client_auth for mTLS client authentication. |
requireCertificateBoundAccessTokens | Optional token-binding flag. Defaults to true for mTLS methods and false for other methods. |
tlsClientAuthSubjectDn | Registered subject distinguished name for tls_client_auth. |
tlsClientAuthSanDns | Registered DNS subject alternative name value or values for tls_client_auth. |
tlsClientAuthSanUri | Registered URI subject alternative name value or values for tls_client_auth. |
tlsClientAuthSanIp | Registered IP subject alternative name value or values for tls_client_auth. |
tlsClientAuthSanEmail | Registered email subject alternative name value or values for tls_client_auth. |
For self_signed_tls_client_auth, configure the certificate public keys as Client App Key Sets with usage SelfSignedTlsClientAuth. For tls_client_auth, configure subject DN or SAN metadata on ClientAppAuthenticationConfiguration; no key set is required.
tls_client_auth
Use tls_client_auth when the client presents a certificate that is validated by TLS termination or a trusted ingress. ProAuth checks the certificate validity period and matches the presented certificate against at least one registered metadata value.
Example client authentication configuration:
{
"tokenEndpointAuthMethod": "tls_client_auth",
"requireCertificateBoundAccessTokens": true,
"tlsClientAuthSubjectDn": "CN=client.example.com,O=Example Corp,C=CH",
"tlsClientAuthSanDns": "client.example.com"
}The following metadata fields are supported and matched exactly:
tlsClientAuthSubjectDntlsClientAuthSanDnstlsClientAuthSanUritlsClientAuthSanIptlsClientAuthSanEmail
Multiple SAN values can be registered as comma-separated, semicolon-separated, or line-separated values.
tls_client_auth requires at least one subject DN or SAN metadata field. JWKS settings are not allowed for this method.
self_signed_tls_client_auth
Use self_signed_tls_client_auth when the client presents a self-signed certificate and ProAuth validates the certificate public key against the client's registered JWKS.
Configure two resources:
- A
ClientAppAuthenticationConfigurationwithtokenEndpointAuthMethodset toself_signed_tls_client_auth. - One or more
ClientAppKeySetrecords with usageSelfSignedTlsClientAuth.
Authentication configuration:
{
"tokenEndpointAuthMethod": "self_signed_tls_client_auth",
"requireCertificateBoundAccessTokens": true
}Key set:
{
"name": "Portal self-signed mTLS certificate keys",
"clientAppId": "10000000-0000-4000-8000-000000000010",
"sourceType": "InlinePublicJwks",
"usage": "SelfSignedTlsClientAuth",
"status": "Active",
"jwksJson": "{\"keys\":[{\"kty\":\"RSA\",\"kid\":\"client-cert-key\",\"n\":\"...\",\"e\":\"AQAB\"}]}"
}RemoteJwksUri key sets are also supported. Remote JWKS fetching is HTTPS-only, does not follow redirects, enforces a short timeout and response-size cap, and rejects loopback, private, link-local, multicast, documentation, and reserved network targets. The certificate public key must match one registered RSA or EC JWK.
Subject DN and SAN metadata fields are not used for self_signed_tls_client_auth. Register both old and new certificate public keys while rotating client certificates.
Forwarded Certificates
Direct TLS client certificates are read from HttpContext.Connection.ClientCertificate. For Kubernetes or reverse-proxy deployments, configure forwarded client certificates per tenant through tenant options. Forwarding is disabled by default.
| Tenant option | Default | Description |
|---|---|---|
ClientCertificateForwardingEnabled | False | Enables trusted forwarded client certificate headers for the tenant. |
ClientCertificateForwardingKnownProxies | empty | Comma-separated proxy IP addresses allowed to forward client certificates. |
ClientCertificateForwardingKnownNetworks | empty | Comma-separated proxy CIDR ranges allowed to forward client certificates. |
ClientCertificateForwardingXForwardedClientCertHeader | X-Forwarded-Client-Cert | Envoy-style header that contains a Cert= value. |
ClientCertificateForwardingPemCertificateHeaders | X-SSL-Client-Cert,X-Client-Cert,ssl-client-cert | Comma-separated header names containing URL-escaped PEM certificates. |
Example tenant option values:
ClientCertificateForwardingEnabled=True
ClientCertificateForwardingKnownNetworks=10.0.0.0/24
ClientCertificateForwardingXForwardedClientCertHeader=X-Forwarded-Client-Cert
ClientCertificateForwardingPemCertificateHeaders=X-SSL-Client-Cert,X-Client-Cert,ssl-client-certProAuth accepts Envoy-style X-Forwarded-Client-Cert values with Cert= and URL-escaped PEM headers. Forwarding is disabled by default. Do not enable certificate forwarding unless the ingress strips untrusted incoming certificate headers and sets them itself after validating the client certificate. For isolated Kubernetes system-test deployments where hosted build agents can come from changing Azure IP ranges, use a loose test-only tenant option such as ClientCertificateForwardingKnownNetworks=0.0.0.0/0,::/0. Only use this when the ingress strips inbound certificate headers from callers and sets the trusted header itself.
Certificate-Bound Access Tokens
For token-endpoint-issued access tokens, ProAuth adds:
{
"cnf": {
"x5t#S256": "base64url-encoded-certificate-sha256-thumbprint"
}
}ProAuth enforces this proof for its OIDC bearer endpoints such as userinfo. External resource servers should require the same presented client certificate and compare its SHA-256 thumbprint with cnf.x5t#S256 from the JWT access token or token introspection response.
Refresh tokens and authorization-endpoint-issued implicit or hybrid access tokens are not certificate-bound. In FAPI mode, mTLS clients still present the configured certificate on refresh-token grants because mTLS is the client's token-endpoint authentication method and satisfies the sender-constrained-token requirement for newly issued access tokens.
Discovery Metadata
Tenant discovery advertises tls_client_auth and self_signed_tls_client_auth in:
token_endpoint_auth_methods_supportedintrospection_endpoint_auth_methods_supportedrevocation_endpoint_auth_methods_supported
PAR support is advertised through pushed_authorization_request_endpoint; ProAuth applies the same configured client authentication method to PAR requests. Discovery also sets tls_client_certificate_bound_access_tokens to indicate support for RFC 8705 certificate-bound access tokens.