Skip to content

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 stored client_secret.

How a client uses it

The client posts to /oauth/token with:

text
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

MethodAlgorithmsVerified against
private_key_jwtRS256, RS384, RS512, ES256, ES384, ES512Client's registration_metadata.jwks (inline) or client_metadata.jwks_uri (fetched with the SSRF guard, same as request objects)
client_secret_jwtHS256, HS384, HS512Client'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:

json
{
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic",
    "client_secret_post",
    "client_secret_jwt",
    "private_key_jwt"
  ]
}

Partial / not yet implemented

  • jti replay trackingexp (and optional nbf) are validated, but the assertion's jti is not yet stored to detect reuse. Most basic OIDC conformance tests pass with exp-only; FAPI requires jti tracking, which can be added later.

Released under the MIT License.