Why cache when token database exists?

Not applicable

I am new to Apigee and am working through an OAuth client credentials design. One piece that is not clear to me is an appropriate way for Edge to take an opaque access token that it has received from the client and look up the JWT associated with that token. I see that this is a scenario in "Short-term general purpose caching":

https://docs.apigee.com/api-platform/cache/persistence-tools#shorttermgeneralpurposecaching

However, I've also seen mention of a token database inside of Apigee Edge. I see that I can retrieve the data from the JWT using the access token, but I would like to get the whole token so that it can be passed to microservices, who use that JWT.

What is the correct way to go here? I've searched around quite a bit and haven't found this scenario used, which makes me think that I've got something wrong.

1 4 426
4 REPLIES 4

Assuming you've created or already have the JWT, when you generate the OAuth token you can add it as a custom attribute using:

<OAuthV2 name="OA-GenerateAccessToken">
    <DisplayName>OA-GenerateAccessToken</DisplayName>
    <Operation>GenerateAccessToken</Operation>
    <Attributes>
        <Attribute name="JWT" ref="your-jwt-var" display="true"/>
    </Attributes>
</OAuthV2>

Then when you "VerifyAccessToken"

<OAuthV2 name="OA-VerifyAccessToken">
    <DisplayName>OA-VerifyAccessToken</DisplayName>
    <Operation>VerifyAccessToken</Operation>
</OAuthV2>

Edge populates the custom attributes as flow variables prefixed with "accesstoken", in this case "accesstoken.JWT".

Very helpful! That led me to the following, which should get me there:

https://docs.apigee.com/api-platform/security/oauth/customizing-access-tokens

Is it a good practice to put the JWT there? I would expect to have to deal with implications around such things as expiration and revocation, and of course security.

You have options for using external tokens, you can associate the JWT with the token as a custom attribute, which makes it hidden to API consumers.

You can also use external tokens as the value of the token in Edge.

https://docs.apigee.com/api-platform/security/oauth/use-third-party-oauth-system

In either case you will need to manage the expiration time for the access_token to keep it in sync with the JWT.

I would expect to have to deal with implications around such things as expiration and revocation, and of course security.

It's a reasonable practice. Yes, you have to consider the lifetimes. The opaque token has an independent lifetime of the JWT. There are these possibilities:

  • opaque token is valid (not expired), JWT is valid (not expired). all is good.
  • opaque token is valid. JWT is expired. What do you do?
  • opaque token is expired. JST is (doesn't matter). Degenerate case.

Really there's just one case that is tricky - and that is.... what do you do with a JWT, that is stored as a custom attribute on an opaque token, if the JWT expires before the opaque token expires? And that's up to you, to decide.

I'll give you an example to consider. To use Google's APIs for Drive and Stackdriver and BigQuery, a client app needs to obtain an opaque oauth access token. To obtain the token, the client needs to generate a self-signed JWT, an ID token. Google's oauth endpoint requires that the ID token passed in a request-for-token must expire within 5 minutes. But the returned access token lasts for an hour.

I have no idea whether Google "stores" the original JWT . That's not the point. The point is to illustrate a case in which it makes sense for a short-lived JWT to be used in generating a longer-lived opaque oauth token.

If you want to synchronize the lifetimes, you can set the ExpiresIn in the OAuthV2/GenerateAccessToken policy to refer to a variable, which you compute based on the expiry of the JWT. The VerifyJWT policy will set a seconds_remaining variable. That value isn't directly appropriate for the ExpiresIn in the OAuthV2/GenerateAccessToken policy, because (maddeningly) ExpiresIn is expressed in MILLIseconds. So you'd need a JS script to multiply by 1000, to get the right number.