aud (Audience) Claim in a JWT
aud lists the recipients the token is intended for. A verifier must reject a token whose audience does not include itself, which is the check that stops a token minted for one service being replayed against another.
At a glance
- Claim
- aud (Audience)
- Defined in
- RFC 7519 section 4.1.3
- Value type
- Array of StringOrURI, or a single string as a shorthand for a one element array
- Required
- Optional in RFC 7519. Required in an OpenID Connect ID token and an RFC 9068 access token.
- Sample value
- ["https://api.example.com", "https://reports.example.com"]
- In the decoder
- Explained by name, listed under Registered claims as Audience. Array values are shown as decoded JSON, not flattened.
In detail
The audience is the set of recipients the token was minted for. RFC 7519 says a verifier that does not identify itself with a value in aud must reject the token. That single rule is what keeps a token issued for a low value internal service from being carried across and accepted by the billing API, so skipping the check quietly turns every service in the estate into the weakest one.
There are two encodings and both are legal. The general case is a JSON array of strings. As a shorthand, a single audience may be written as a bare string. Consumers have to handle both, which is exactly where hand rolled checks fail: comparing the claim to a string with a simple equality test works until the issuer starts emitting a one element array and every request begins failing at once.
What goes in the value is a naming decision, not a security one, but a bad choice makes the check useless. Identity providers usually want the resource URL of the API, such as https://api.example.com, because it is unique and already meaningful. A human label like Reports API is fine until a second environment uses the same label and a staging token starts passing production checks.
The decoder shows aud under Registered claims as Audience and renders an array as JSON rather than joining it into one string, so you can see whether the issuer sent one value or several. It does not know which service you are, so it cannot tell you whether the audience matches: that comparison belongs in the code that consumes the token.
Examples
// Single audience, shorthand string form
{ "aud": "https://api.example.com" }
// Multiple audiences, array form, with azp naming the client
{
"aud": ["https://api.example.com", "https://reports.example.com"],
"azp": "web-dashboard"
}Things that catch people out
- Treating aud as always a string. The array form is equally valid and a strict equality comparison against it silently fails or, worse, is skipped by a catch all branch.
- Not checking aud at all because the signature verified. A valid signature only proves the issuer minted the token, not that it was minted for you.
- Putting several unrelated APIs in one aud array hands each of them a token that works on the others. Mint separate tokens instead when the services do not trust each other equally.
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 →iss (Issuer) Claim in a JWT
The iss claim names who issued a token. What goes in it, why validators compare it byte for byte, and how the decoder displays it.
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.
client_id Claim in a JWT Access Token
The client_id claim names the OAuth client an access token was issued to. How it differs from sub and azp, where it is required, and decoder behaviour.
exp (Expiration Time) Claim in a JWT
The exp claim sets when a JWT stops being accepted. NumericDate format, clock skew allowances, and the four expiry states the decoder shows.
nbf (Not Before) Claim in a JWT
The nbf claim marks the earliest time a JWT may be accepted. When a not before time is worth setting, and how the decoder flags a future one.
iat (Issued At) Claim in a JWT
The iat claim records when a JWT was created. What it is good for, why it is not an expiry, and the age and lifetime figures the decoder derives.
Tools for this
- JWT Decoder Free online JWT decoder - decode and inspect JSON Web Tokens without sending them to a server