docs: clarify exp and iat claim precedence for private key JWTs (#12110)

This PR updates the "Private Key JWT Auth for Service Accounts"
documentation to explicitly clarify the relationship between the exp
(expiration) and iat (issued at) claims.

Previously, the documentation didn't make it clear what happens if a
developer sets an exp claim far into the future. This update clarifies
that while the exp value is strictly enforced, the iat claim takes
precedence if the exp is set to more than 1 hour in the future (i.e.,
ZITADEL will reject the JWT once the iat is older than 1 hour,
regardless of the exp time).

**Changes included:**

Updated the description of the exp claim in the JWT payload section to
highlight the 1-hour iat limit enforcement.
This commit is contained in:
Federico Coppede
2026-04-27 14:58:50 +02:00
committed by GitHub
parent 314b1b50dd
commit f96a9c54ac
@@ -118,7 +118,7 @@ Payload:
* `sub`: The application. Set this to the same value as `userId`.
* `aud`: Your [Custom Domain](../../../concepts/features/custom-domain).
* `iat`: The Unix timestamp when the JWT is created/signed (must be no older than 1 hour).
* `exp`: The Unix timestamp when this assertion expires.
* `exp`: The Unix timestamp when this assertion expires. The value of `exp` is strictly enforced. However, if `exp` is set to more than 1 hour in the future, `iat` will take precedence (the JWT will stop working once the `iat` timestamp is older than 1 hour).
For further details, see the [JWT with private key](/apis/openidoauth/authn-methods#jwt-with-private-key) API reference.
@@ -165,7 +165,7 @@ With the encoded JWT from the previous step, craft a POST request to ZITADEL's t
```bash
curl --request POST \
--url https:/$CUSTOM-DOMAIN/oauth/v2/token \
--url https://${CUSTOM_DOMAIN}/oauth/v2/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
--data scope='openid' \
@@ -235,4 +235,4 @@ By following these steps and adhering to best practices, you can securely manage
* [JWT with private key](/apis/openidoauth/authn-methods#jwt-with-private-key) API reference
* [Accessing ZITADEL API](../zitadel-apis/access-zitadel-apis)
* [Token introspection with private key JWT](../token-introspection/private-key-jwt)
* [Token introspection with private key JWT](../token-introspection/private-key-jwt)