Client Authentication Methods
Whenever a client calls a protected endpoint at ThunderID, such as token, introspection, PAR, or DCR (when secured), it must prove which client it is. The token_endpoint_auth_method setting on the application picks how. The choice is fixed per application and applies uniformly to every protected endpoint.
ThunderID supports four methods, three for confidential clients and one (none) for public clients. The relevant specs are RFC 6749 §2.3, RFC 6749 §2.1 (public clients), and RFC 7523 (JWT bearer client authentication).
Comparing the Methods
| Method | Credential type | Where it travels | Confidentiality | Use when |
|---|---|---|---|---|
client_secret_basic | Shared secret | Authorization: Basic header | TLS-protected | Server-side apps that can store a secret. Default. |
client_secret_post | Shared secret | POST body parameters | TLS-protected | Clients that can't set custom headers |
private_key_jwt | Asymmetric key | Signed JWT in POST body | No secret on the wire | High-security deployments; FAPI; rotating credentials without redeployment |
none | None | No credentials | None | Public clients (browser apps, mobile apps) that can't store a secret |
client_secret_basic
The default for new confidential clients. Credentials travel in a standard HTTP Authorization: Basic header, Base64-encoded.
POST /oauth2/token HTTP/1.1
Host: thunderid.example.com
Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&scope=api:read
The Base64 payload is the literal string client_id:client_secret. ThunderID URL-decodes neither the client ID nor the secret. Pass them verbatim.
client_secret_post
Same credentials as client_secret_basic, but in the body instead of the header. Useful when the HTTP client cannot set custom headers, or when a corporate proxy strips them.
POST /oauth2/token HTTP/1.1
Host: thunderid.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=$CLIENT_ID
&client_secret=$CLIENT_SECRET
&scope=api:read
private_key_jwt
The client signs a short-lived JWT assertion with its private key. ThunderID verifies the signature against the application's registered public key (either inline JWKS or a JWKS_URI it fetches). No secret ever crosses the wire.
Registering Client Keys
The OAuth client configuration must have either a JWKS (inline JSON Web Key Set) or a JWKS_URI (HTTPS URL ThunderID fetches) configured. See OAuth client certificate below for the rules.
Assertion Claims
The client builds and signs a JWT with these claims:
| Claim | Value |
|---|---|
iss | The client_id |
sub | The client_id |
aud | The token endpoint URL (https://thunderid.example.com/oauth2/token) |
jti | A unique identifier; ThunderID rejects replays |
exp | A short expiry (seconds, not minutes) |
iat | Issued-at time |
Example Request
POST /oauth2/token HTTP/1.1
Host: thunderid.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIs...
&scope=api:read
The client_assertion_type value is fixed: urn:ietf:params:oauth:client-assertion-type:jwt-bearer.
Supported Assertion Algorithms
RS256, RS512, PS256, ES256, ES384, ES512, EdDSA. Symmetric algorithms (HS*) are not accepted.
none
Reserved for public clients, applications that cannot keep a secret, like single-page apps and native mobile apps. No credentials travel in the request; client identity is asserted by the client_id parameter alone.
Public clients must use PKCE on the authorization code flow. ThunderID sets pkceRequired automatically when token_endpoint_auth_method is none.
POST /oauth2/token HTTP/1.1
Host: thunderid.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=$CODE
&redirect_uri=https://app.example.com/callback
&client_id=$CLIENT_ID
&code_verifier=$CODE_VERIFIER
Where Each Method Applies
The chosen method applies uniformly to every endpoint that requires client authentication:
| Endpoint | Method enforced |
|---|---|
POST /oauth2/token | Yes |
POST /oauth2/par | Yes |
POST /oauth2/introspect | Yes |
POST /oauth2/dcr/register | Optional: DCR can be configured to require authentication |
OAuth Client Certificate
A client certificate is the public-key material ThunderID stores in the OAuth client configuration (inboundAuthConfig[].config.certificate) and uses to:
- Verify signed JWT assertions for
private_key_jwtclient authentication. - Encrypt ID tokens when Token Formats for that application is
JWEorNESTED_JWT. - Sign or encrypt UserInfo responses when UserInfo response format requires it.
The OAuth client certificate field has three possible types:
| Type | Description |
|---|---|
None | No certificate configured. The application cannot use private_key_jwt, encrypted ID tokens, or encrypted UserInfo. |
JWKS | Inline JSON Web Key Set provided as a JSON object in the OAuth client configuration. |
JWKS_URI | HTTPS URL of the application's JWKS endpoint. ThunderID fetches the public keys from this URL. The URL must use HTTPS. |
JWKS and JWKS_URI are mutually exclusive: setting both on the same application returns an error.
This certificate is separate from ThunderID's own signing keys (see JWKS), which is the public-key endpoint resource servers use to verify ThunderID-issued tokens.
Try It in ThunderID
- Console
- Dynamic Client Registration
- Open Applications or Agents in the ThunderID Console and select your client.
- Open the Advanced Settings tab and find the Client Authentication section.
- Select one of
client_secret_basic,client_secret_post,private_key_jwt, ornone. - For
private_key_jwt, also configure a Certificate (JWKS or JWKS_URI) in the OAuth client settings. - Save.
POST /oauth2/dcr/register
Content-Type: application/json
{
"client_name": "My API Client",
"grant_types": ["client_credentials"],
"token_endpoint_auth_method": "private_key_jwt",
"jwks_uri": "https://service.example.com/.well-known/jwks.json"
}
Related Guides
- Dynamic Client Registration, register a client and pick its auth method programmatically
- Pushed Authorization Requests, uses the same client authentication method
- Token Introspection, uses the same client authentication method
- Token Formats, the OAuth client certificate is also used to encrypt ID tokens and UserInfo responses