Client authentication in your tenant
Decide how each confidential client proves who it is at the token, introspection and revocation endpoints.
The same controls apply to BTL's own organization under BTL Admin, OAuth Management.
Methods
Each client has one Client authentication method, chosen in Clients. A request that uses another method, or two at once, is refused.
| Method | What the client sends |
|---|---|
client_secret_basic | Its client ID and secret in an Authorization: Basic header. The default for confidential clients. |
client_secret_post | client_id and client_secret in the form body. |
private_key_jwt | A short JWT signed with its own private key, in client_assertion, with client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer (RFC 7523). No secret travels. |
none | Only client_id. The only method for public clients, which cannot keep a secret. |
Changing a client's method revokes nothing: its tokens stay valid, and its next request must use the new method. Discovery lists all four methods and the assertion algorithms ES256, PS256, RS256 and EdDSA.
Secrets and rotation
In Access Token Management, Client authentication secret generates a secret for a confidential client. It is shown once. Choose how long the current secret keeps working: no overlap stops it at once, or keep it for an hour, a day or seven days, so every copy of the application can switch first. While a previous secret still works, the card shows when it ends, and End the previous secret now stops it early. Rotating again during an overlap ends the older secret. Secrets are stored only as hashes.
The new secret can have No expiry or expire after a duration from 60 seconds to one year. The card shows its deadline. An overlap never extends the previous secret's original expiry, and rotating an already expired secret cannot make it work again. Plan replacement before the deadline and update every application instance that uses it. These choices apply independently to each client, including clients in BTL's own organization.
Signed assertions
For private_key_jwt, register the client's public keys under Client public keys: paste a JWKS of 1 to 5 keys, RSA of at least 2048 bits, EC P-256 or Ed25519, each with its own kid. A key with private members, such as d, is refused. The client signs an assertion for each request:
{"iss": "<client ID>", "sub": "<client ID>", "aud": "<issuer or token endpoint URL>",
"exp": <at most 10 minutes ahead>, "iat": <now>, "jti": "<random, new each time>"}The audience must be the issuer identifier alone, as a string, for every client, as draft-ietf-oauth-rfc7523bis and FAPI 2.0 require. The same assertion then works at the token, pushed authorization, introspection, revocation, device authorization and CIBA endpoints, including on the mutual TLS alias. An assertion addressed to an endpoint URL, or to several audiences, is refused with invalid_client and the Audit reason invalid_client_assertion. This is not a tenant setting: accepting endpoint URLs is what lets a malicious server that copies your token endpoint's address collect assertions it can replay here. The header names the algorithm and, when the client has several keys, the kid. Each jti works once until the assertion expires; a second use is refused. The lab toolkit makes a key pair with btl-lab jwk and signs an assertion with btl-lab assertion.
Keys from a URL
Instead of pasting keys, give a jwks_uri where the client publishes them. The tenant fetches it under a fixed policy: https on the default port, a public host name that is not inside this environment's tenant addresses, no redirects, five seconds and at most 64 KiB. Only public signing keys it supports are used. The keys are kept for five minutes; an assertion with a kid the copy does not have fetches again at most once a minute, so a client can rotate its keys. If the URL cannot be read, a copy up to an hour old keeps working. Each fetch, and each failure, is recorded in the tenant's protocol Audit as client_keys_fetched or client_keys_unavailable.
Refusals and history
A failed authentication answers invalid_client with HTTP 401, and so does a request that sends no credentials where they are required, such as a public client asking for client credentials or introspection (client_authentication_required), as RFC 6749 section 5.2 describes. A grant the tenant's Flow Policy leaves off answers unsupported_grant_type (grant_disabled), and one the tenant offers but the client may not use answers unauthorized_client. At the authorization endpoint, a response type the tenant does not offer is unsupported_response_type, and one the client may not use is unauthorized_client. The protocol Audit records why: unsupported_auth_method, invalid_client_assertion, client_assertion_audience (signed correctly, but not addressed to the issuer identifier), assertion_expired, assertion_replayed or client_keys_unavailable. Generating secrets, ending a previous secret and registering keys each need the credential permission, which Tenant Admin holds, and each is recorded in Audit with the overlap or the number of keys, never the secret or key itself.