Specification: RFC 7523, with OpenID Connect Core §9 for the private_key_jwt method name
A client with a registered key pair proves its identity by signing a short-lived JWT, so no shared secret exists. Versola implements this form of the RFC (client authentication, section 2.2). It does not implement using a JWT as an authorization grant (section 2.1).
Status
Partially implemented. Checked claims: 13 of 15.
Client authentication
-
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearerwithclient_assertion - Accepted at
/token,/par,/introspectand/revoke(PrivateKeyJwtSpec) -
issandsubmust both equal theclient_id; aclient_idsent beside the assertion must match - Signature verified against the client’s registered JWK Set, with an algorithm from the advertised set (
ES256,PS256by default) -
exprequired and not further ahead than the tenant’s client-assertion maximum (30–900 s, default 300 s) -
jtirequired and single use, tracked across replicas (PrivateKeyJwtSpec) -
iatandnbfup to 60 s in the future are accepted, further ahead is refused (PrivateKeyJwtSpec) -
audon astandardtenant: the issuer or the endpoint URL; on afapi2tenant: exactly the issuer, as a single string (PrivateKeyJwtSpec) - A client registered for
private_key_jwtcannot authenticate with a secret, and a request that carries two methods is refused (PrivateKeyJwtSpec) - A client that registered no keys cannot authenticate with an assertion
- Keys for
self_signed_tls_client_authdo not authenticate an assertion - The method and its algorithms are advertised in
token_endpoint_auth_methods_supportedandtoken_endpoint_auth_signing_alg_values_supported - Central can generate the key pair at registration (
generateJwks,ES256,PS256orRS256); the private half is returned once and never stored - JWT bearer authorization grant (section 2.1,
urn:ietf:params:oauth:grant-type:jwt-bearer) — not implemented -
client_secret_jwt— not implemented
Notes
- The same registered key set verifies signed request objects, so a request object that carries
subis refused; see RFC 9101. - The assertion
jtinamespace is shared with request objects: ajtispent on one cannot be spent on the other.
Where to look
Security profiles explains the aud and lifetime rules that differ between profiles.