Hashing Cached Access Tokens

Hi @dchiesa1 

We have a constraint to use JWKS based approach as our IDP team has expressed some challenges about this. 

The current architecture in our Enterprise has two API Gateways one is Apigee X and Axway (on prem). There are few APIs which are exposed through Apigee X but reach out to on-prem data source through on-prem gateway.
The API owners have reached out to us requesting to minimize multiple calls to the IDP server for the access token validation.

We want to cache the tokens in Apigee X so that the validation is done only once when the user requests the services. I have implemented the Cache of access tokens, but I did read that there is a limit of 2KB in Apigee Cache and in our case there are some users who have tokens which are more than this limit.

If I want to hash the tokens before caching it, I saw there is an option available within Templates, is this something which is advised and if yes I assume it needs to be done from an AssignVariable element, where I used a variable to hash the token and then cache this variable containing the hashed token.

I am not quite sure if HMAC policy also allows to do for the same where we can hash a token before we cache it.

Thanks,

Debjit

Solved Solved
2 2 100
1 ACCEPTED SOLUTION

I have some ideas, but I want to make sure I understand clearly first.

The API owners have reached out to us requesting to minimize multiple calls to the IDP server for the access token validation.

So I understand that the IDP is issuing JWT... and you are using them as access tokens. Is that right?

And your IDP team is saying

  • Don't use our JWKS endpoint, because.... REASONS.
  • Don't call directly to IDP's token validation endpoint, because ,... it's not set up to handle the volume we would expect.

is that about right?

If so, I think your situation is overconstrained and the correct solution is to persuade the IDP team to do the right thing. Provide the right JWKS and encourage people to use it.

JWT are federated, to allow any party to validate a token, without contacting the issuer. The only requirement is the validating party must have access to the public key. So the model is: the validating party connects to the issuing party (in your case, what you are calling the IDP), ONCE, to retrieve the set of public keys. This is normally done through a well-known JWKS endpoint.  aka "wke". A good example is the well-known endpoint for Google OAuth : https://www.googleapis.com/oauth2/v3/certs . Once you have that set of keys, you can use them freely, validate a million JWTs, and without ever  re-contacting the issuer. That is the beauty of JWT!  It allows federated validation. The issuer does not need to participate in validation. There are real scale and performance benefits to this approach.

There's an alternative way to validate a JWT, which some issuers have supported, which is to expose a validation endpoint. The idea is, an actor that wants to validate a JWT can send in the JWT to the validation endpoint, and ask the issuer "please tell me if this token is valid?"

My opinion: That "works" but it basically subverts the main benefit of the JWT model, which is that any party can validate a signed JWT. If you have to send the JWT back to the issuer to ask for validation, what is the point of having a JWT? The JWT is inferior to an opaque token in two significant ways: It's larger. It's slower to validate. Read more about the JWT vs opaque question, on the internet, or here on the Apigee community. The MAIN BENEFIT of JWT is that anyone can validate them. Therefore relying on a remote validation endpoint, ... just gives you poor performance. Why not just use Opaque tokens, which are faster and lighter? 

But anyway, as I understand what you're saying, your IDP has a validation endpoint, but the IDP team is telling you not to use it. ??  So, you should use NEITHER the JWKS NOR the validation endpoint. 

This is starting to sound kinda Kafkaesque. I cannot help you solve that. You need a better IDP team. You need an IDP team that gives you a usable JWKS endpoint, one that supports plain GET requests, a team that doesn't recommend against using JWKS. There is no getting around that. The constraints they're putting on you are dumb. They're not doing their job, if that's what they're telling you.  I have no better or more polite way to say that. THEY HAVE ONE JOB, and they're not doing it.

While they're not doing their job, you're looking for a way to make progress.  So you thought, maybe I can hash the JWT and cache it...  Ok, that's a reasonable attempt to resolve an unreasonable situation.  But Hashing JWT is also a non-optimal idea, in my opinion. You noted the main reason, but there are others.

If I had to solve the challenge of validating a JWT, but "not validating too much" (!?!?!), I would build a token exchange.

  • Receive a JWT from the IDP
  • validate it once, presumably via a JWKS. 
  • After validating, issue an Apigee-native (and opaque) access_token
  • the calling app can store that apigee token, and replay it when requesting service

it will be lightning fast to validate the opaque access token within the Apigee proxy. This is just a token exchange pattern. Recently I discussed this pattern in a different reply here, and I built an example to illustrate it. Check it out.

Debjit, I think you need some architectural support within your company. I'm not going to be able to help you further here. Considering the use of HMAC policies to hash JWT.... and so many other things you've asked about... this is the wrong approach. I understand you're just trying to make progress, and that's commendable. But it's the wrong approach. The solution is outside of your purview. You need to escalate inside your company. Someone with authority in your company, a director or a VP,  needs to knock some heads together, and to get the IDP team to do the right thing. You need an architect to get everyone aligned on a rational, workable, sane strategy. And  for people who don't want to get aligned, they should get re-assigned. Get on the bus, or get out of the way.

My advice to you: Don't build on faulty foundations. Get the identity system right, and build from there. Don't distort your API proxy behavior because your identity system isn't supporting the normal requirements of an API or application team.

Good luck!

View solution in original post

2 REPLIES 2

I have some ideas, but I want to make sure I understand clearly first.

The API owners have reached out to us requesting to minimize multiple calls to the IDP server for the access token validation.

So I understand that the IDP is issuing JWT... and you are using them as access tokens. Is that right?

And your IDP team is saying

  • Don't use our JWKS endpoint, because.... REASONS.
  • Don't call directly to IDP's token validation endpoint, because ,... it's not set up to handle the volume we would expect.

is that about right?

If so, I think your situation is overconstrained and the correct solution is to persuade the IDP team to do the right thing. Provide the right JWKS and encourage people to use it.

JWT are federated, to allow any party to validate a token, without contacting the issuer. The only requirement is the validating party must have access to the public key. So the model is: the validating party connects to the issuing party (in your case, what you are calling the IDP), ONCE, to retrieve the set of public keys. This is normally done through a well-known JWKS endpoint.  aka "wke". A good example is the well-known endpoint for Google OAuth : https://www.googleapis.com/oauth2/v3/certs . Once you have that set of keys, you can use them freely, validate a million JWTs, and without ever  re-contacting the issuer. That is the beauty of JWT!  It allows federated validation. The issuer does not need to participate in validation. There are real scale and performance benefits to this approach.

There's an alternative way to validate a JWT, which some issuers have supported, which is to expose a validation endpoint. The idea is, an actor that wants to validate a JWT can send in the JWT to the validation endpoint, and ask the issuer "please tell me if this token is valid?"

My opinion: That "works" but it basically subverts the main benefit of the JWT model, which is that any party can validate a signed JWT. If you have to send the JWT back to the issuer to ask for validation, what is the point of having a JWT? The JWT is inferior to an opaque token in two significant ways: It's larger. It's slower to validate. Read more about the JWT vs opaque question, on the internet, or here on the Apigee community. The MAIN BENEFIT of JWT is that anyone can validate them. Therefore relying on a remote validation endpoint, ... just gives you poor performance. Why not just use Opaque tokens, which are faster and lighter? 

But anyway, as I understand what you're saying, your IDP has a validation endpoint, but the IDP team is telling you not to use it. ??  So, you should use NEITHER the JWKS NOR the validation endpoint. 

This is starting to sound kinda Kafkaesque. I cannot help you solve that. You need a better IDP team. You need an IDP team that gives you a usable JWKS endpoint, one that supports plain GET requests, a team that doesn't recommend against using JWKS. There is no getting around that. The constraints they're putting on you are dumb. They're not doing their job, if that's what they're telling you.  I have no better or more polite way to say that. THEY HAVE ONE JOB, and they're not doing it.

While they're not doing their job, you're looking for a way to make progress.  So you thought, maybe I can hash the JWT and cache it...  Ok, that's a reasonable attempt to resolve an unreasonable situation.  But Hashing JWT is also a non-optimal idea, in my opinion. You noted the main reason, but there are others.

If I had to solve the challenge of validating a JWT, but "not validating too much" (!?!?!), I would build a token exchange.

  • Receive a JWT from the IDP
  • validate it once, presumably via a JWKS. 
  • After validating, issue an Apigee-native (and opaque) access_token
  • the calling app can store that apigee token, and replay it when requesting service

it will be lightning fast to validate the opaque access token within the Apigee proxy. This is just a token exchange pattern. Recently I discussed this pattern in a different reply here, and I built an example to illustrate it. Check it out.

Debjit, I think you need some architectural support within your company. I'm not going to be able to help you further here. Considering the use of HMAC policies to hash JWT.... and so many other things you've asked about... this is the wrong approach. I understand you're just trying to make progress, and that's commendable. But it's the wrong approach. The solution is outside of your purview. You need to escalate inside your company. Someone with authority in your company, a director or a VP,  needs to knock some heads together, and to get the IDP team to do the right thing. You need an architect to get everyone aligned on a rational, workable, sane strategy. And  for people who don't want to get aligned, they should get re-assigned. Get on the bus, or get out of the way.

My advice to you: Don't build on faulty foundations. Get the identity system right, and build from there. Don't distort your API proxy behavior because your identity system isn't supporting the normal requirements of an API or application team.

Good luck!

Thanks Dino for your time and advise. I agree with your points about the IDP team being responsible more in giving us a better solution to get the tokens validated.

Apologies for so many back and forth posts on the community. 
I will look at your post which you shared above.

Regards,

Debjit