private_key_jwt Client Authentication
Private_key_jwt is an OAuth 2.0 / OpenID Connect client authentication method where the client proves its identity by presenting a signed JWT "assertion" instead of a shared client secret. The authorization server validates this assertion using the client's registered public key and, if valid, treats the client as authenticated.
Concept and Positioning
Private_key_jwt is an asymmetric-key-based client authentication mechanism
defined in OIDC Core and built on the JWT client assertion profile in RFC
7521 / RFC
7523. It is used at the token
endpoint as a more secure alternative to client_secret_basic,
client_secret_post. In high-security profiles like FAPI,
private_key_jwt is either recommended or mandated for confidential clients.
Registration and Key Material
Before the flow can work, the client must be registered as a confidential client
with its token endpoint authentication method set to private_key_jwt. The
client generates an asymmetric key pair (for example, RSA or EC) and keeps the
private key locally while publishing the corresponding public key to the AS,
usually via:
-
A static JWK Set value (
jwks) in dynamic or static client metadata. -
A
jwks_urithat the AS can dereference to obtain the client's JWK Set.
The AS associates these keys with the client_id and uses them to validate
signatures on incoming assertions. Key rotation then consists of updating the
registered JWK Set while the client switches to the new private key.
Assertion Structure and Claims
Client authentication is performed with a signed JWT sent as client_assertion
and accompanied by
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer.
The JWT header and payload have specific requirements presented below.
JOSE Header:
| Claim | Description |
|---|---|
alg | A permitted asymmetric JWS algorithm (for example, RS256, PS256, ES256) negotiated at registration or constrained by server policy. |
kid | A key identifier that matches a JWK in the registered JWK Set when multiple keys exist. |
typ | Often set to JWT (optional but common). |
JWT Claims (Payload)
| Claim | Description |
|---|---|
iss | The client_id. |
sub | The client_id (same as iss for client auth). |
aud | The token endpoint URL (or the issuer/endpoint identifier required by the AS), preventing replay at other endpoints or servers. |
jti | A unique identifier for this assertion instance, used by the AS to detect replays. |
iat | Issued-at timestamp (numeric date). |
exp | Expiry timestamp, typically a short window (for example, 60–300 seconds after iat). |
These semantics ensure that the assertion is bound to one client, to one audience, and to a narrow time window, and that individual assertions cannot be reused.
Token Endpoint Request Flow
In a typical authorization_code exchange with private_key_jwt, the client sends:
-
grant_type=authorization_code(or another supported grant). -
The grant-specific parameters (
code,redirect_uri, etc.). -
Client assertion parameters:
-
client_id=<client_id> -
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer -
client_assertion=<signed-JWT>
-
The assertion is usually signed using the client's private key on the local
system or HSM, producing a compact JWS. The request body is
application/x-www-form-urlencoded; the assertion itself is transmitted as an
opaque string from the token endpoint's perspective.
Server-Side Validation Steps
On receipt, the authorization server performs an ordered set of checks:
-
Syntactic checks
-
Parse the JWT.
-
Ensure required parameters (
client_assertion,client_assertion_type,client_id) are present and consistent.
-
-
Client and key resolution
-
Resolve the client configuration using
client_id. -
Verify that the configured token endpoint auth method is
private_key_jwt. -
Load the client's JWK Set from stored metadata or via
jwks_uri. -
Select the key by
kidwhere present or byalg/ key use whenkidis omitted.
-
-
Signature verification
-
Verify the JWS signature using the resolved public key.
-
Ensure the
algused is allowed for this client and endpoint.
-
-
Claim validation
-
issandsubmatchclient_id. -
audmatches the expected token endpoint or issuer identifier. -
expis in the future but within configured maximum assertion lifetime. -
iatis within acceptable clock skew. -
jtihas not been seen before (usually via a replay cache keyed on client_id + jti within the assertion lifetime window).
-
-
Replay protection and outcome
-
If any check fails, the server returns an OAuth error (for example,
invalid_clientorinvalid_request). -
If all checks pass, the client is considered authenticated, and normal token processing proceeds (authorization_code validation, scope checks, token issuance).
-
The replay cache can be implemented in-memory, distributed cache, or database, with expiration aligned to assertion lifetime; this is essential because the AS cannot rely solely on TLS to prevent capture and replay of an assertion.
Security Properties
Private_key_jwt has several useful properties in comparison to symmetric client secrets:
-
The client's private key is never sent over the wire; only the signed assertion is transmitted. Compromise of the AS database does not reveal the client's private key.
-
Public keys can be distributed and rotated without moving secret material, reducing risk during onboarding and rotation workflows.
-
Each authentication event is bound to a distinct signed object with
jti,iat, andexp, yielding strong replay protection when combined with a replay cache. -
Non-repudiation is stronger: a given assertion can be tied to a specific key controlled by the client, which is useful for regulated environments.
private_key_jwt Client Authentication to Raidiam APIs
Client applications registered in Raidiam Connect can be configured to use the
private_key_jwt client authentication method to prove their identity to
Connect's Authorization Server and obtain access tokens for Raidiam APIs.
When you register a client in Connect, the platform automatically:
-
Publishes a dedicated
jwks_urifor that client -
Registers the client at Raidiam's Authorization Server via Dynamic Client Registration (DCR), including the published
jwks_uriin the registration
Whenever you generate or upload a signing key pair for your application, the
public key is added to the client's JWKS document at the jwks_uri. This
enables Raidiam's Authorization Server to retrieve the key and verify the
signatures on your private_key_jwt client assertions.