Verify JWT, Audience and Scopes with 3rd Party JWKS

Hi,

I'm trying to test APIGee API Proxy to verify Auth0 Generated Access Tokens, not only verify the Signature from a JWKS, expiration, audience but also scopes. I found out that Verify JWT Policy does most of it, but it doesn't support scopes verification. I'm trying then to combine it with OAuthV2 Policy in sequence, just to verify scopes, but the latter fails "keymanagement.service.invalid_access_token".

Can you help me to solve this issue?

0 6 1,035
6 REPLIES 6

Can you help me to solve this issue?

Yes

The scopes in the third-party issued JWT are not related to scopes on an OAuth token issued by Apigee. They have the same name, and you might think of them as representing the same kinds of information, but the Apigee OAuthV2/VerifyAccessToken policy doesn't know about JWT and doesn't validate JWT.

Today in the VerifyJWT policy you can verify "well known" claims like audience, issuer, subject. And you can verify an EXACT match for other claims like scopes or projectid or groupid or etc. But today you cannot configure the VerifyJWT policy to check for presence of a single value in a claim that is a list of values. Maybe this is what you already discovered.

An example: If the payload of the signed JWT is like this:

{
  "aud": "https://backend.example.com",
  "iss": "https://as.example.com",
  "exp": 1614713257,
  "iat": 1614712957,
  "sub": "bdc@example.com",
  "scopes": [
    "read",
    "update"
  ]
}

...then you can configure VerifyJWT to match the scopes claim that contains ["read", "update"] in EXACTLY that order. But you cannot configure VerifyJWT to check that the scopes claim contains just one of those scopes. Similarly if the scopes claim in the JWT is a space-separated string, like so :

"scopes": "read update"

...then within the VerifyJWT policy, you can check for an exact match, but you cannot check for presence of ONE of those scope strings.

To verify ONE value, today, you must follow the VerifyJWT policy with a second check. The VerifyJWT policy will implicitly set a variable containing the value of the scopes claim, and the subsequent check can just examine that variable. A good way to do this is to use a RaiseFault policy wrapped with a Condition. In the condition, test that value with a regex, checking for the scope of interest. If the regex FAILS, raise the fault (insufficient scope).

It looks like this:

<Step>
    <Name>VerifyJWT-1</Name>
</Step>
<Step>
    <Condition>NOT (jwt.VerifyJWT-1.decoded.claim.scopes ~~ "^\[.*update.*\]$")</Condition>
    <Name>RF-InsufficientScope</Name>
</Step>

There is an outstanding feature request to allow you to use VerifyJWT to check a list claim (like scopes) in a JWT, for the presence of a specific value. The internal reference for this F.R. is b/169068726. I don't have a specific estimate on the time this will become available. We hope, soon.

Thanks for the quick response.

Would lose to much performance if instead of using a condition I use an assign message policy to set a scopes definition variable for the endpoint and then javascript policy to match scopes in token with scopes in variable?

Nope, that would work fine. a check embedded within JavaScript will be a little slower than a check implemented right in a Condition, but.... the right-hand-side of the Condition needs to be fixed, so ... you cannot use a Condition for a "variable scope check".

The JS approach will work just fine.

Can you please paste it in comment box about how you define variable in assign message policy and Javascript that you have used

please ask a new question.  Here's why I ask you to do that: When people squeeze new questions into the comments of an old, existing question, it makes it very difficult for future readers to follow the stream, to understand what is being asked and answered, and where. In fact, even I am not even clear on exactly what you are asking about.  Maybe it is the same scenario as originally asked here or ... maybe it is something similar, but not quite the same.  Asking a new question helps with that. Feel free to reference the existing question~  "I have a question similar to THIS ONE [insert link] but mine is a little different.  ..."  

I can give you the answer to part 1 of your Q:  AssignVariable within AssignMessage lets you define variables.  As for the JS part, please move that conversation to a new question. 

Thanks for contributing the the Apigee community!

Not applicable

We have implemented third party jwks. This is as below.

We have configured the 3rd party jwks key in Apigee kvm.

The user will get the jwt token which will have claims and audience. Then the user will request the service with that token, in Apigee jwt verify the signature validation will happen against the jwks key in kvm. Next the audience and claims get verified using javascript.