From f96a9c54acd724df18b1549d528744900a2783fa Mon Sep 17 00:00:00 2001 From: Federico Coppede Date: Mon, 27 Apr 2026 09:58:50 -0300 Subject: [PATCH] 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. --- .../guides/integrate/service-accounts/private-key-jwt.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/docs/content/guides/integrate/service-accounts/private-key-jwt.mdx b/apps/docs/content/guides/integrate/service-accounts/private-key-jwt.mdx index c96245481..1e3b5d088 100644 --- a/apps/docs/content/guides/integrate/service-accounts/private-key-jwt.mdx +++ b/apps/docs/content/guides/integrate/service-accounts/private-key-jwt.mdx @@ -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) \ No newline at end of file