Does VerifyJWT policy check against nbf, iat, and exp on default?

Reading up on the VerifyJWT policy, I see where you can't add iat, nbf, and exp as additional claims but I don't see any set attributes for them either (like audience, subject, iss). Are these verified by default?

I just want to confirm I don't need to add additional attributes to cover them.

Solved Solved
1 2 1,676
1 ACCEPTED SOLUTION

Yes, the VerifyJWT policy implicitly checks the validity times on the inbound JWT.

None of {iat, nbf, exp} are required. But if they are present, then VerifyJWT checks them. The documentation has this to say:

When this policy executes, Edge verifies the signature of a JWT, and verifies that the JWT is valid according to the expiry and not-before times if they are present.

The JWT specification does not provide clear guidance on whether the iat claim ought to be used in validity checks. In other words, the spec has nothing to say about what to do if the JWT includes an iat which is in the future. Should that JWT be considered valid? We are unsure. In the absence of formal guidance in the specification, we have decided that the VerifyJWT policy in Apigee will, by default, validate that the iat is less than or equal to "now". In other words, if a client presents a JWT to Apigee and your proxy executes VerifyJWT on it, then VerifyJWT will throw a fault if iat refers to a time that lies in the future. (this is modulated by the max Time allowance, similar to how it applies to the exp claim).

You can turn that behavior off; you can tell VerifyJWT to ignore the iat claim for the purposes of validation, using the IgnoreIssuedAt element. https://docs.apigee.com/api-platform/reference/policies/verify-jwt-policy#ignoreissuedat

One could imagine a case in which a verifier wants to accept only JWT that have no more than 120 seconds of validity. Today, there is no way for a VerifyJWT policy to (a) verify that there is an expiry present, or (b) verify that the actual lifetime of a JWT is less than or equal to a particular limit.

If you want your API Proxy to validate that there IS an expiry, or that the lifetime is less than a certain limit, then you need to do it in two steps. First VerifyJWT. Then, test that the seconds_remaining variable exists, or that seconds_remaining exists and is less than a specific value. You can do that in a Condition wrapping a RaiseFault, subsequent to the VerifyJWT policy.

<Step>
  <Name>VerifyJWT-1</Name>
</Step>
<Step>
  <Condition>jwt.VerifyJWT-1.seconds_remaining = null || jwt.VerifyJWT-1.seconds_remaining GreaterThan 300 </Condition>
  <Name>RF-InvalidJWT</Name>
</Step>

View solution in original post

2 REPLIES 2

Yes, the VerifyJWT policy implicitly checks the validity times on the inbound JWT.

None of {iat, nbf, exp} are required. But if they are present, then VerifyJWT checks them. The documentation has this to say:

When this policy executes, Edge verifies the signature of a JWT, and verifies that the JWT is valid according to the expiry and not-before times if they are present.

The JWT specification does not provide clear guidance on whether the iat claim ought to be used in validity checks. In other words, the spec has nothing to say about what to do if the JWT includes an iat which is in the future. Should that JWT be considered valid? We are unsure. In the absence of formal guidance in the specification, we have decided that the VerifyJWT policy in Apigee will, by default, validate that the iat is less than or equal to "now". In other words, if a client presents a JWT to Apigee and your proxy executes VerifyJWT on it, then VerifyJWT will throw a fault if iat refers to a time that lies in the future. (this is modulated by the max Time allowance, similar to how it applies to the exp claim).

You can turn that behavior off; you can tell VerifyJWT to ignore the iat claim for the purposes of validation, using the IgnoreIssuedAt element. https://docs.apigee.com/api-platform/reference/policies/verify-jwt-policy#ignoreissuedat

One could imagine a case in which a verifier wants to accept only JWT that have no more than 120 seconds of validity. Today, there is no way for a VerifyJWT policy to (a) verify that there is an expiry present, or (b) verify that the actual lifetime of a JWT is less than or equal to a particular limit.

If you want your API Proxy to validate that there IS an expiry, or that the lifetime is less than a certain limit, then you need to do it in two steps. First VerifyJWT. Then, test that the seconds_remaining variable exists, or that seconds_remaining exists and is less than a specific value. You can do that in a Condition wrapping a RaiseFault, subsequent to the VerifyJWT policy.

<Step>
  <Name>VerifyJWT-1</Name>
</Step>
<Step>
  <Condition>jwt.VerifyJWT-1.seconds_remaining = null || jwt.VerifyJWT-1.seconds_remaining GreaterThan 300 </Condition>
  <Name>RF-InvalidJWT</Name>
</Step>

Update: We have logged two feature requests:

  • b/169068476 - ability to check that there IS an expiry
  • b/168905687 - ability to check that the lifetime of the token falls under a specified limit.

The work for these has not been done, and there's no estimated delivery date at this time.