# The azp (Authorized Party) Claim

`azp` names the party an [ID token](https://www.abblix.com/en/docs/glossary-overview#id-token-identity-token) was issued to. When present it holds that party's OAuth 2.0 client ID, and its value is a case-sensitive string.

That is the whole definition. Almost everything else written about `azp` describes a rule that OpenID Connect Core no longer states, which is why the claim causes more confusion than a single optional string should.

## What the specification says now

[OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#IDToken), incorporating errata set 2, makes three statements about `azp` in the ID token section:

- It is **OPTIONAL**.
- If present, it **MUST** contain the client ID of the authorized party.
- In practice it only occurs when extensions beyond the scope of the specification are in use, so implementations not using such extensions are **encouraged not to use it**, and to ignore it when it does occur.

The third point is the one that surprises people. `azp` is not a general-purpose field for recording who asked; it is a hook that specific extensions may define behaviour for, and a provider that implements no such extension has no reason to emit it at all.

## Why most explanations disagree

Earlier revisions of the specification carried a concrete rule that is still quoted everywhere. [The pre-errata text](https://openid.net/specs/openid-connect-core-1_0-final.html#IDToken) said the claim was *only needed* when the ID token had a single audience value and that audience was different than the authorized party, and that it *may* be included even when the authorized party was the sole audience. That is where the familiar summary comes from: "`azp` appears when `aud` is not the client".

Errata set 2 removed it. The current text does not tie `azp` to the shape of `aud`, does not require it in any situation, and pushes implementations away from emitting it. Anything you read that explains `azp` in terms of a single audience differing from the client is describing superseded text, and the difference is not cosmetic: it changes the claim from "usually present in this case" to "usually absent".

The practical consequence is that neither presence nor absence of `azp` tells you anything on its own. It is not a signal you can build a check on unless the provider documents an extension that defines it.

## azp compared with aud

The two claims answer different questions, and only one of them is something a client validates unconditionally.

| | `aud` | `azp` |
|---|---|---|
| Question it answers | who is this token for | which party requested it |
| Required | yes, in every ID token | no |
| Type | string or array of strings | single string |
| Client's duty | MUST verify its own client ID is present, and MUST reject a token carrying audiences it does not trust | SHOULD verify its client ID is the value, when the claim is present and an extension defines it |

An ID token's audience is its client, so in the ordinary case `aud` already carries the client ID and `azp` would only repeat it. The claim earns its place only where an extension makes the requesting party distinguishable from the audience, and where that extension says what to do about it.

## What a client should validate

[Section 3.1.3.7](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation) sets the validation rules for an ID token, and `azp` is a conditional entry in that list rather than a step of its own.

- Validate `iss`, `aud`, signature, `exp` and [nonce](https://www.abblix.com/en/docs/glossary-overview#nonce) as always. These are unconditional and are where the security of the token actually rests.
- If the implementation uses an extension that results in `azp` being present, validate the value as that extension specifies.
- That validation **MAY** include checking that the client's own client ID is the value.

Written as code, the rule is: do not require `azp`, do not reject a token for lacking it, and do not silently ignore it either when your provider documents a meaning for it. Rejecting tokens that carry no `azp` is the most common way to break interoperability with a conformant provider, because a conformant provider is encouraged not to send one.

There is one more `azp` rule that only appears during a refresh. [Section 12.2](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokenResponse) provides that where extensions put `azp` in the original ID token, they may require the refreshed token to carry the same value, and where the original had none, they may require that the new one has none either. Consistency across a session is therefore an extension's business, not something a client can assume by default.

## azp and access tokens

`azp` is defined for ID tokens. The JWT profile for OAuth 2.0 access tokens, [RFC 9068](https://datatracker.ietf.org/doc/html/rfc9068), does not use it: an access token identifies its client through the `client_id` claim. A JWT that carries `azp` but no `client_id` is therefore shaped like an ID token, and that distinction is useful when a token arrives without its context, such as at a [token exchange](https://www.abblix.com/en/docs/glossary-overview#token-exchange) endpoint.

## azp in Abblix OIDC Server

Abblix OIDC Server reads `azp` and does not issue it, which follows the current specification directly: no shipped extension gives the claim a meaning here, and the specification asks implementations in that position not to emit it.

Reading it has one concrete use. `JwtSubjectTokenResolver` has to work out which client a `subject_token` was issued to, so that a pairwise `sub` can be opened against the right sector and the confused-deputy guard has an origin to compare against. Access and refresh tokens name their client in `client_id`; an ID token does not, and identifies its client through a sole audience or, where several audiences are present, through `azp`. The resolver therefore takes `client_id`, then `azp`, then a sole audience, in that order. A token with several audiences and neither claim leaves the origin genuinely undeterminable, and the resolver records it as unknown rather than guessing.

## Common mistakes

- **Requiring `azp`.** A conformant provider is encouraged not to send it. A client that rejects tokens without it will fail against most providers.
- **Deriving authorization from it.** `azp` says who requested the token, not what that party may do. Scope and audience carry the authority.
- **Assuming it appears whenever `aud` has several values.** That was never quite the old rule, and it is not the current one.
- **Trusting it without the signature.** Like every claim in a JWT, `azp` means nothing until the token's signature is verified against the issuer's keys.
