Integrating with Cloud IAP

This post is part 3 of a series discussing Cloud IAP:

In the last post, we discussed that each request that Cloud IAP passes to a backend appliation contains a X-Goog-Iap-Jwt-Assertion header. This header contains an IAP JWT assertion that looks a bit like an IdToken, but is not an IdToken.

The primary purpose of an IdToken is to enable a relying party to identify the user. In contrast, the primary purpose of the IAP JWT assertion is to enable the backend application to verify that the request has been properly vetted by Cloud IAP.

Validating an IAP JWT assertion

To understand why validating the IAP JWT assertion is important, consider the following threats:

Accidental disabling of Cloud IAP: You might accidentally disable Cloud IAP, causing all requests to be passed unvetted.

To protect against this threat, an application should check for the existence of the JWT assertion.

Sidestepping Cloud IAP: If firewall rules are not properly configured, a malicious client might sidestep Cloud IAP and send a request directly to the backend application. To overcome the check for the assertion, it might send a fake assertion:

Fake assertion

To protect against sidestepping and fake assertions, a backend application should verify the signature of the JWT against Cloud IAP’s JWKS.

Because IAP JWT assertions are JWTs, any JWT-compliant OAuth or OpenID Connect library should be able to perform such validation.

Replay: A malicious client that somehow got hold of an IAP JWT assertion might keep replaying the assertion.

To protect against such replays, a backend application should verify the expiration of the assertion as encoded in the exp claim.

Assertions from a different IAP instance: Finally, it is possible that the request passed some Cloud IAP instance, but not the right one. This is a rare case and probably requires some configuation screw-up to happen, but still…

Wrong IAP

To verify that an IAP JWT assertion is indeed intended for this backend application and not for some other party, a backend application should verify the audience claim (aud).

Using the IAP JWT assertion

As disucssed in the first part of the series, the purpose of Cloud IAP is not to replace application-level access control, but to serve as an additional layer of defense.

Depending on access control requirements of the application, you might:

  • Prompt for username and password, and validate these credentials against the application’s own database, Active Directory, or some other LDAP server.
  • Use Open ID Connect to obtain an IdToken and access tokens. Using the access token, the application can then access GCP APIs or other Google APIs.

Performing a second Open ID Connect flow might seem backwards or redundant – why even use Cloud IAP if you have to implement OpenID Connect anyway?

First, this redundancy is a manifestation of Cloud IAP being an additional layer of defense, not a replacement for custom access control.

Secondly, and more importantly, notice that Cloud IAP and
OpenID Connect serve different, complementing purposes
in this case:

  • Cloud IAP checks whether the user is authorized to access the application at all. And it does so by not only verifying the user’s identity, but also by taking additional signals such as device and location into account.
  • OpenID Connect allows an application to obtain a user’s consent (authorization) to access APIs and data on his behalf.

Other protocols

So far, I only talked about web applications – and for the longest time, these were the only resources that Cloud IAP was able to protect. But Cloud IAP also supports TCP forwarding, which allows it to be used for other protocols such as SSH and RDP as well. How this works and how it can be used will be the topic for another day…

« Back to home