JWT vs PoP JWT

Hi @Dino-at-Google,

I came across some reading around concept of Proof of Possession in case of JWT - https://tools.ietf.org/html/rfc7800. I wanted to know if we have any sample APIs implemented around this.

Regards,

Santosh

Solved Solved
1 5 2,720
1 ACCEPTED SOLUTION

Hi Santosh

No I have not assembled an example of Apigee Edge engaging in an exchange or verification of JWT POP Tokens. (Update: yes I have; see the proxy attached to my comment below)

As you probably can see from reading RFC 7800, it's not super complicated.

Especially if you use Asymmetric keys, which requires no key exchange.

Here's what a super simple demonstration would look like, if you use Apigee Edge as the issuer. Build an API Proxy.

  1. create a conditional flow POST /poptoken (or whatever) which accepts a JSON payload including a public key (JWK format I guess) and any other claims you'd like to embed in the JWT
  2. Within that conditional flow, verify the inputs and then use GenerateJWT with the Apigee Edge private key as the signer. Embed the JWK passed by the client into the JWT. Use whatever claim name you like. The spec says use "cnf".
  3. The client then
    1. encrypts or signs a nonce with his own private key
    2. sends that JWT POP token along with the encrypted nonce to the recipient. This token includes the "cnf" claim which contains the jwk.
    3. the recipient can then verify that JWT using the public key of the issuer, and then instantiate a public key from the embedded jwk (cnf claim).
    4. Then recipient decrypts or verify the signature on the nonce, thus verifying that the client holds the private key corresponding to the jwk in the JWT POP.

It's possible to imagine using Apigee Edge to do a little more... For example a separate Apigee Edge proxy (or the same) could act as a facade for the recipient and could perform the verification of the encrypted or signed nonce as I described above. Inn the general case, you'd need some custom Java or JavaScript to do that, since there is no general "verify RSA-SHA256 signature" utility builtin to Apigee Edge.

IF you are ok with using a JWT as a nonce, then ... you don't need the custom Java or JavaScript. You can just use two VerifyJWT policies: one to verify the issuer's signature on the JWT POP, and one to verify the client's signature on the "nonce JWT". The nonce JWT in this case can be pretty thin, maybe just include jti, iss (client id), iat, and exp as claims.

I can imagine doing this, but I haven't built anything like this.

View solution in original post

5 REPLIES 5

Hi @Dino-at-Google,

Can you please help if there is any documentation around this for Apigee?

Hi Santosh

No I have not assembled an example of Apigee Edge engaging in an exchange or verification of JWT POP Tokens. (Update: yes I have; see the proxy attached to my comment below)

As you probably can see from reading RFC 7800, it's not super complicated.

Especially if you use Asymmetric keys, which requires no key exchange.

Here's what a super simple demonstration would look like, if you use Apigee Edge as the issuer. Build an API Proxy.

  1. create a conditional flow POST /poptoken (or whatever) which accepts a JSON payload including a public key (JWK format I guess) and any other claims you'd like to embed in the JWT
  2. Within that conditional flow, verify the inputs and then use GenerateJWT with the Apigee Edge private key as the signer. Embed the JWK passed by the client into the JWT. Use whatever claim name you like. The spec says use "cnf".
  3. The client then
    1. encrypts or signs a nonce with his own private key
    2. sends that JWT POP token along with the encrypted nonce to the recipient. This token includes the "cnf" claim which contains the jwk.
    3. the recipient can then verify that JWT using the public key of the issuer, and then instantiate a public key from the embedded jwk (cnf claim).
    4. Then recipient decrypts or verify the signature on the nonce, thus verifying that the client holds the private key corresponding to the jwk in the JWT POP.

It's possible to imagine using Apigee Edge to do a little more... For example a separate Apigee Edge proxy (or the same) could act as a facade for the recipient and could perform the verification of the encrypted or signed nonce as I described above. Inn the general case, you'd need some custom Java or JavaScript to do that, since there is no general "verify RSA-SHA256 signature" utility builtin to Apigee Edge.

IF you are ok with using a JWT as a nonce, then ... you don't need the custom Java or JavaScript. You can just use two VerifyJWT policies: one to verify the issuer's signature on the JWT POP, and one to verify the client's signature on the "nonce JWT". The nonce JWT in this case can be pretty thin, maybe just include jti, iss (client id), iat, and exp as claims.

I can imagine doing this, but I haven't built anything like this.

Hi @Dino-at-Google,

Thank you fro helping with this. I will try this and see how it looks. Although I was looking at the key exchange mechanism also and in one of the implementation that I saw has this pop token as an additional token that is used as an additional measure to notify that the actual token that a token master had minted was indeed for that client only(who is sending the request now). I am not sure if it is a overkill but wanted to know your view on both the points.

Regards,

Santosh

Maybe it is overkill. Maybe not. Let's understand the purpose of the POP token flow.

There are three parties in the POP token flow:

  • Presenter
  • Issuer
  • Recipient

The presenter is... typically the client. It contacts the issuer and asks for a POP token, and later presents that token to the recipient.

The Issuer issues the POP token to the presenter; the token is signed with his own key.

The recipient verifies the POP token.

Because the recipient verifies the token, which is signed by the "issuer", the recipient can be assured that the issuer has verified the presenter's identity.

Now, we may design the recipient to treat that JWT as a bearer token, which means: when ANY client presents a JWT signed by the issuer, the recipient assumes that the "sub" claim (subject) identifies the holder. That's not necessarily true. If some malicious third party ("Mallory") has hijacked the JWT, then Mallory can present that JWT to recipient and recipient thinks Mallory is Bob.

Contrariwise, If the recipient treats the JWT as a POP Token, then ... the recipient checks

  • that the issuer signed the POP JWT
  • that the POP JWT contains a cnf claim
  • that the cnf claim points to a public key in some way (jwk)
  • and finally, that the presenter holds the private key that matches the public key.

This last step involves verifying a second signature, on a thing the POP Token flow calls a "nonce". You could use a 2nd JWT for that nonce.

It's not "overkill" to use POP Token flow if you want the guarantees associated with it; if you want the recipient to be assured that the presenter holds a private key. Some scenarios demand additional security protection; the recipient wants to be assured that the authenticated client possesses a cryptographic key. Perhaps for securing point-to-point messages when the client requests access to protected resource.


Attached please find an example showing how this might work.

I have a proxy with 2 endpoints: one for the issuer and one for the recipient.

It isn't necessary that Apigee Edge act as both issuer and recipient, but it could.

This is just an example.

apiproxy-jwt-pop-20190806.zip

Hi @Dino-at-Google,

Thank you so much for putting this aptly and also highlighting use of it. I see that you have created a new article as well that can help to understand this more elaborately - https://community.apigee.com/content/kbentry/71494/pop-using-jwt-to-prove-possession-of-a-key.html

Regards,

Santosh