client_id Claim in a JWT Access Token
client_id names the OAuth client the token was issued to. In a token obtained on a user's behalf it sits beside sub, which names the user, and the two answer genuinely different questions.
At a glance
- Claim
- client_id (Client Identifier)
- Defined in
- RFC 8693 section 4.3
- Value type
- String, the client identifier as registered at the authorization server
- Required
- Required in an RFC 9068 JWT access token. Optional elsewhere.
- Sample value
- reporting-job
- In the decoder
- Shown under Custom claims with its raw value. It is not one of the seven claims explained by name.
In detail
Three claims name parties and they are routinely mixed up. sub is who the token is about, usually the end user. aud is who is meant to consume it, usually an API. client_id is which registered application asked for it. In a client credentials grant there is no user at all, so sub is often set to the client identifier too, and that coincidence is where the confusion usually starts.
RFC 9068, the profile that standardizes what a JWT access token looks like, makes client_id required, along with iss, exp, aud, sub, iat and jti. That gives a resource server a reliable answer to which application is calling, which is what audit logs and per client rate limits need. Without it, a resource server can only see the user and has to infer the caller from context.
It also enables authorization rules that depend on the application rather than the person. A finance API may accept the same user through an interactive dashboard but refuse an unattended batch client, or apply different limits to each. Those rules are only sound when the client identifier comes from the signed token, since anything sent in a header alongside it can be changed freely by the caller.
In an ID token the equivalent question is answered by azp, not client_id, because ID tokens describe an authentication rather than an API grant. The decoder shows whichever the issuer emitted, under Custom claims, with the raw value. Seeing which of the two is present is often enough to work out whether you are looking at an ID token or an access token.
Examples
{
"iss": "https://auth.example.com",
"aud": "https://api.example.com",
"client_id": "reporting-job",
"sub": "reporting-job",
"scope": "read:invoices",
"jti": "9a8f2c14-0b3d-4e77-9c2a-5f1e8d0b7a63"
}sub repeating the client identifier is normal here: there is no user, so the client is the subject.
Things that catch people out
- Reading sub as a user identifier without checking the grant type. In a client credentials token it is the client, and treating it as a person creates ghost user records.
- Trusting a client identifier sent in a request header or query parameter. Only the value inside the signed token is meaningful.
- Looking for client_id in an ID token. That document uses azp to name the party it was issued to.
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 →azp (Authorized Party) Claim in a JWT
The azp claim names the client an ID token was issued to. When OpenID Connect requires it, how it differs from aud, and what the decoder shows.
scope Claim in a JWT Access Token
The scope claim carries the granted OAuth scopes inside an access token. Why it is one space delimited string, how to check it, and what the decoder shows.
sub (Subject) Claim in a JWT
The sub claim says who the token is about. Why it is only unique within one issuer, what pairwise subjects change, and how the decoder shows it.
act (Actor) Claim in a JWT
The act claim names the party acting on behalf of the subject. How nesting records a delegation chain, and why the decoder shows it as raw JSON.
may_act (Authorized Actor) Claim in a JWT
The may_act claim states which party may act on behalf of the subject. How it gates a token exchange, how it pairs with act, and what the decoder shows.
cnf (Confirmation) Claim in a JWT
The cnf claim binds a token to a key its holder must prove. How mTLS and DPoP use it, why it stops replay of a stolen token, and decoder limits.
Tools for this
- JWT Decoder Free online JWT decoder - decode and inspect JSON Web Tokens without sending them to a server