RFC 7523 — JWT Profile for Client Authentication
Spec: datatracker.ietf.org/doc/html/rfc7523Status: Full
RFC 7523 §3 (and OpenID Connect Core §9) define how a client can authenticate to the token endpoint by sending a signed JWT — the client assertion — instead of a client_secret. AuthHero accepts both flavors:
private_key_jwt— asymmetric, verified against the client's JWKS.client_secret_jwt— symmetric (HMAC), verified against the client's storedclient_secret.
How a client uses it
The client posts to /oauth/token with:
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertion=<signed JWT>client_id may be sent as a form field or omitted (in which case it is derived from the assertion's sub claim). All standard grant types (authorization_code, client_credentials, refresh_token) honor the assertion in place of client_secret. PKCE (code_verifier) still applies to the authorization-code grant when present.
Sending both client_secret and client_assertion is rejected with invalid_request.
Supported algorithms
| Method | Algorithms | Verified against |
|---|---|---|
private_key_jwt | RS256, RS384, RS512, ES256, ES384, ES512 | Client's registration_metadata.jwks (inline) or client_metadata.jwks_uri (fetched with the SSRF guard, same as request objects) |
client_secret_jwt | HS256, HS384, HS512 | Client's stored client_secret |
alg=none is always rejected.
Required claims (RFC 7523 §3)
The verifier enforces:
iss==sub==client_id— the assertion identifies and authenticates the same client.aud— must match the token endpoint URL or the OP issuer.exp— required, validated with 30 s leeway.nbf— optional, validated with 30 s leeway when present.
Configuring a client
Set token_endpoint_auth_method on the client to client_secret_jwt or private_key_jwt. Dynamic Client Registration (RFC 7591) accepts the same values. For private_key_jwt, supply the client's public keys via jwks (inline) or jwks_uri.
Discovery
/.well-known/openid-configuration advertises:
{
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"client_secret_jwt",
"private_key_jwt"
]
}Partial / not yet implemented
jtireplay tracking —exp(and optionalnbf) are validated, but the assertion'sjtiis not yet stored to detect reuse. Most basic OIDC conformance tests pass withexp-only; FAPI requiresjtitracking, which can be added later.
Related AuthHero documentation
- OpenID Connect Core — §9 client authentication
- RFC 9101 — JAR — uses the same JWT signature verifier on the authorize endpoint
- RFC 7591 — Dynamic Client Registration