Security Best Practices: Validating Audience (aud) Claims in ZITADEL Access Tokens
Understanding risks and implementing effective mitigations beyond audience checks
Problem Overview
In OAuth 2.0, the audience (aud
) claim indicates the intended recipient of a token. A client must verify the tokens audience claims and ensure that at least one audience value matches its unique identifier. While verifying aud is essential, using it as your sole authorization check is insufficient. ZITADEL allows clients to request arbitrary audience scopes (urn:zitadel:iam:org:project:id:{projectID}:aud
), resulting in tokens that include an audience even if the user lacks explicit permissions for that audience. Relying solely on aud can therefore grant unauthorized access if additional checks are not implemented.
Current ZITADEL Behavior
- When requesting the
urn:zitadel:iam:org:project:id:{projectID}:aud
scope, ZITADEL issues access tokens containing the requested aud claims without verifying the requesting user's grants. - Token introspection correctly reports such tokens as inactive (active: false) if the audience is unauthorized, helping prevent misuse.
- In the Project Role Settings, you can enable the following checks for human users performing an interactive login flow:
- Check authorization on Authentication: If set, users are only allowed to authenticate if any role is assigned to their account.
- Check for Project on Authentication: It is checked whether the user's organization has this project. If not, the user cannot be authenticated.
- Check authorization on Authentication: If set, users are only allowed to authenticate if any role is assigned to their account.
Recommended Mitigations
To securely handle ZITADEL-issued access tokens, implement the following best practices:
- Layered Authorization Checks:
- Always verify specific roles, scopes or custom claims in addition to checking the aud claim. You should also check the
iss
claim, signature and expiration of the token. - Reject tokens lacking the necessary roles or custom claims, even if the audience matches.
- Always verify specific roles, scopes or custom claims in addition to checking the aud claim. You should also check the
- Token Introspection:
- Use ZITADEL’s introspection endpoint to confirm token validity, roles, and active state.
- Reject tokens reported inactive (active: false) or without sufficient privileges.
- Use ZITADEL’s introspection endpoint to confirm token validity, roles, and active state.