Managing Cloud IAP sessions

This page describes how Cloud Identity-Aware Proxy (Cloud IAP) handles a request with an expired session and how to make sure that AJAX app requests are successful.

Cloud IAP session flow

Cloud IAP sessions are tied to the underlying Google login session.

When using the standard Cloud IAP login flow, the user receives a session cookie that references their Google login session. The session cookie is a JWT signed by the Google account system. Cloud IAP uses this cookie to confirm that the user is still signed into their Google account.

Cloud IAP requires a user to sign back into their Google account before accessing a Cloud IAP-secured app. The following are a few situations that require the user to sign back in:

  • The user signed out of their account
  • Their account was suspended
  • The account requires a password reset

If a user is signed out, Cloud IAP detects a Google account state change within a couple minutes. Once detected, Cloud IAP invalidates the session.

Cloud IAP re-checks Cloud Identity and Access Management (Cloud IAM) authorization for all requests during valid sessions. Updates to a Cloud IAP-secured app's Cloud IAM access policy might take a few minutes to take effect.

JWT token expiration

For the standard Cloud IAP login flow, the one-hour expiry time in the Cloud IAP session cookie is ignored. Login sessions are instead secured with account state checks.

For programmatic authentication, Cloud IAP does honor the exp claim in the JWT.

Expired session responses

Cloud IAP returns different responses for expired sessions based on the type of request.

Non-AJAX requests

For non-AJAX requests, the user is redirected to the Google OAuth flow to refresh the session. If the user is still signed in to Google, this redirect is transparent.

AJAX requests

Cloud IAP returns an HTTP 401: Unauthorized response code. This is because of HTTPS Cross-Origin Resource Sharing (CORS) restrictions in the Google OAuth server. Note that AJAX request detection can't be done perfectly. If you're getting a 302 response instead of 401 to AJAX requests, an X-Requested-With header with a value of "XMLHttpRequest" can be added to AJAX requests. This tells Cloud IAP that the request originates from JavaScript.

Handling an HTTP 401 AJAX response

To support a failed AJAX request caused by a user no longer signed into their Google account, handle the HTTP 401 response from the Cloud IAP-secured app. To do this, update your app code to handle the error, provide a refresh link, and close the window.

Step 1: Modify your app code

The following example shows how to modify your app code to handle the HTTP 401 response and provide a session refresh link to the user:

if (response.status === 401) {
  statusElm.innerHTML = 'Login stale. <input type="button" value="Refresh" onclick="sessionRefreshClicked();"/>';
Step 2: Install an onclick handler

The sample code below installs an onclick handler that closes the window after the session is refreshed:

var iapSessionRefreshWindow = null;

function sessionRefreshClicked() {
  if (iapSessionRefreshWindow == null) {
    iapSessionRefreshWindow ="/_gcp_iap/do_session_refresh");
    window.setTimeout(checkSessionRefresh, 500);
  return false;

function checkSessionRefresh() {
  if (iapSessionRefreshWindow != null && !iapSessionRefreshWindow.closed) {
    fetch('/favicon.ico').then(function(response) {
      if (response.status === 401) {
        window.setTimeout(checkSessionRefresh, 500);
      } else {
        iapSessionRefreshWindow = null;
  } else {
    iapSessionRefreshWindow = null;
Was this page helpful? Let us know how we did:

Send feedback about...

Identity-Aware Proxy Documentation