cnf (Confirmation) Claim in a JWT
cnf binds a token to a key that the legitimate presenter must prove possession of. It turns a bearer token, which works for whoever holds it, into one that only works for the party holding the matching private key.
At a glance
- Claim
- cnf (Confirmation)
- Defined in
- RFC 7800
- Value type
- JSON object holding one confirmation method member
- Required
- Optional. Present only on sender constrained tokens.
- Common members
- jwk and kid from RFC 7800, x5t#S256 for mTLS bound tokens in RFC 8705, jkt for DPoP in RFC 9449
- In the decoder
- Shown under Custom claims as decoded JSON. The tool verifies the token signature, not the separate possession proof.
In detail
A plain access token is a bearer credential: anyone who obtains a copy can use it until it expires. cnf changes the deal by naming a key inside the signed token. The resource server then requires the caller to demonstrate possession of the matching private key on every request, so a stolen token on its own is useless without the key that never travels with it.
Three shapes turn up in practice. RFC 7800 defines jwk, which embeds the public key, and kid, which references one. RFC 8705 uses x5t#S256 to hold the SHA-256 thumbprint of the client certificate used on the mutually authenticated connection. RFC 9449 uses jkt for the thumbprint of the DPoP key, and the client proves possession by signing a short lived proof for each request.
The claim is only as good as the enforcement. A resource server that reads cnf and does not verify the corresponding proof gets no protection whatsoever, and a client that is issued a constrained token but presents it as a plain bearer token will simply be refused. Both halves have to be deployed, which is why the claim is common in financial grade profiles and rare elsewhere.
The decoder shows cnf under Custom claims as JSON so you can see which confirmation method is in use and read the thumbprint or embedded key. It cannot check the proof, because that lives outside the token: a DPoP proof is a separate JWT sent in its own header, and an mTLS binding is a property of the connection. What it does verify, in your browser, is the access token's own signature.
Examples
{
"iss": "https://auth.example.com",
"aud": "https://api.example.com",
"client_id": "mobile-app",
"cnf": { "jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" }
}jkt is the base64url SHA-256 thumbprint of the client's DPoP public key. Sample value only.
{
"iss": "https://auth.example.com",
"cnf": { "x5t#S256": "bwcK0esc3ACC3DB2Y5_lESsXE8o9ltc05O89jdN-dg2" }
}The thumbprint must match the client certificate presented on the mutually authenticated connection.
Things that catch people out
- Accepting a token with cnf without checking the proof. The claim is a requirement on the resource server, not a protection that applies by itself.
- Confusing cnf with the header parameters that carry keys. cnf is a payload claim about the presenter's key; jwk and kid in the header describe the signing key.
- Assuming a constrained token still works as a bearer token during a migration. It does not, and clients have to be updated first.
Try it: JWT Decoder
Paste a token to decode the header and payload, read the claims and expiry, and verify the signature in your browser. Nothing is uploaded.
JWT Decoder
LOCAL · Browser-OnlyDecode and inspect JSON Web Tokens without sending them to a server
Related JWT claims and algorithms
All jwt claims and algorithms →jwk (JSON Web Key) Header Parameter in a JWT
The jwk header embeds the public key in the token itself. Why trusting it verifies nothing, where it is legitimate, and how the decoder treats it.
x5t#S256 (X.509 SHA-256 Thumbprint) Header
The x5t#S256 header holds a SHA-256 thumbprint of the signing certificate. How it is computed, where mTLS bound tokens reuse the value, and what to check.
jti (JWT ID) Claim in a JWT
The jti claim gives a JWT a unique identifier. How it supports replay detection and denylists, what it costs to store, and how the decoder shows it.
email Claim in an OpenID Connect ID Token
The email claim carries the end user's email address. Why it must not be used as an account key, what scope returns it, and what the decoder shows.
email_verified Claim in an OpenID Connect ID Token
The email_verified claim says whether the provider verified the address. Why account linking depends on it, the string true trap, and decoder behaviour.
preferred_username Claim in an ID Token
The preferred_username claim carries a shorthand name for the user. Why OpenID Connect says it is neither unique nor stable, and how the decoder shows it.
Tools for this
- JWT Decoder Free online JWT decoder - decode and inspect JSON Web Tokens without sending them to a server