This page describes how to secure your app with signed IAP headers. When configured, Identity-Aware Proxy (IAP) uses JSON Web Tokens (JWT) to make sure that a request to your app is authorized. This protects your app from the following risks:
- IAP is accidentally disabled
- Misconfigured firewalls
- Unauthorized access from within the project
To help secure your app, you must use signed headers for all app types.
Alternatively, if you have an App Engine standard environment app, you can use the Users API.
Compute Engine and GKE health checks don't include JWT headers and IAP doesn't process health checks. If your health check returns access errors, make sure that you have the health check configured correctly in the Google Cloud console and that your JWT header validation allows the health check path. For more information, see Create a health check exception.
Before you begin
To secure your app with signed headers, you'll need the following:
- An application that you want users to connect to.
- A third-party JWT library for your language that supports
the
ES256algorithm.
Securing your app with IAP headers
To secure your app with the IAP JWT, verify the header,
payload, and signature of the JWT. The JWT is in the HTTP request header
x-goog-iap-jwt-assertion. If an attacker bypasses IAP, the
attacker can forge the IAP unsigned identity headers,
x-goog-authenticated-user-{email,id}. The IAP JWT provides
a more secure alternative.
Signed headers provide secondary security in case someone bypasses
IAP. When IAP is enabled, IAP
strips the x-goog-* headers provided by the client when the request goes
through the IAP serving infrastructure.
Verifying the JWT header
Verify that the JWT's header conforms to the following constraints:
| JWT Header Claims | ||
|---|---|---|
alg |
Algorithm | ES256 |
kid |
Key ID |
Must correspond to one of the public keys listed in the
IAP key file, available in two different formats:
https://www.gstatic.com/iap/verify/public_key
and
https://www.gstatic.com/iap/verify/public_key-jwk
|
Ensure that the JWT was signed by the private key that corresponds to
the token's kid claim. First, retrieve the public key from one of two places:
https://www.gstatic.com/iap/verify/public_key. This URL contains a JSON dictionary that maps thekidclaims to the public key values.https://www.gstatic.com/iap/verify/public_key-jwk. This URL contains the IAP public keys in JWK format.
After you have the public key, use a JWT library to verify the signature.
IAP periodically rotates its public keys. To make sure that you can always verify the JWTs, see Automate public key caching.
Verifying the JWT payload
Verify the JWT's payload conforms to the following constraints:
| JWT Payload Claims | ||
|---|---|---|
exp |
Expiration time | Must be in the future. The time is measured in seconds since the UNIX epoch. Allow 30 seconds for skew. The maximum lifetime of a token is 10 minutes + 2 * skew. |
iat |
Issued-at time | Must be in the past. The time is measured in seconds since the UNIX epoch. Allow 30 seconds for skew. |
aud |
Audience |
Must be a string with the following values:
|
iss |
Issuer |
Must be https://cloud.google.com/iap.
|
hd |
Account domain |
If an account belongs to a hosted domain, the
hd claim is provided to differentiate the
domain the account is associated with.
|
google |
Google claim |
If one or more access levels
apply to the request, their names are stored within the google
claim's JSON object, under the access_levels key, as an array
of strings.
When you specify a device policy and the Org has access to the device data, the |
You can get the values for the aud string mentioned above by accessing the
Google Cloud console, or you can use the gcloud command-line tool.
To get aud string values from the Google Cloud console, go to the
Identity-Aware Proxy settings
for your project, click More next to the Load Balancer resource, and then
select Signed Header JWT Audience. The Signed Header JWT dialog that
appears shows the aud claim for the selected resource.
If you want to use the gcloud CLI
gcloud command-line tool to get the aud string values, you'll need to know
the project ID. You can find the project ID on the
Google Cloud console
Project info card, then run the specified commands for each value.
Project number
To get your project number using the gcloud command-line tool, run the following command:
gcloud projects describe PROJECT_ID
The command returns output like the following:
createTime: '2016-10-13T16:44:28.170Z' lifecycleState: ACTIVE name: project_name parent: id: '433637338589' type: organization projectId: PROJECT_ID projectNumber: 'PROJECT_NUMBER'
Service ID
To get your service ID using the gcloud command-line tool, run the following command:
gcloud compute backend-services describe SERVICE_NAME --project=PROJECT_ID --global
The command returns output like the following:
affinityCookieTtlSec: 0 backends: - balancingMode: UTILIZATION capacityScaler: 1.0 group: https://www.googleapis.com/compute/v1/projects/project_name/regions/us-central1/instanceGroups/my-group connectionDraining: drainingTimeoutSec: 0 creationTimestamp: '2017-04-03T14:01:35.687-07:00' description: '' enableCDN: false fingerprint: zaOnO4k56Cw= healthChecks: - https://www.googleapis.com/compute/v1/projects/project_name/global/httpsHealthChecks/my-hc id: 'SERVICE_ID' kind: compute#backendService loadBalancingScheme: EXTERNAL name: my-service port: 8443 portName: https protocol: HTTPS selfLink: https://www.googleapis.com/compute/v1/projects/project_name/global/backendServices/my-service sessionAffinity: NONE timeoutSec: 3610
Retrieving the user identity
If all of the preceding verifications are successful, retrieve the user identity. The ID token's payload contains the following user information:
| ID Token Payload User Identity | ||
|---|---|---|
sub |
Subject |
The unique, stable identifier for the user. Use this value instead of the
x-goog-authenticated-user-id header.
|
email |
User email | User email address.
|
Following is sample code to secure an app with signed IAP headers: