Setting up context-aware access with Identity-Aware Proxy Stay organized with collections Save and categorize content based on your preferences.
This guide describes how to extend Identity-Aware Proxy (IAP) access policies usingaccess levels and theIdentity and Access Management (IAM) Conditions Framework.Access levels allow access restrictions to resources based on IP address and end-user device attributes. IAM conditions allow access restrictions based on URL hosts, paths, date, and time.
For example, depending on the policy configuration, your sensitive app can:
- Grant access to all employees if they're using a trusted corporate device fromyour corporate network.
- Grant access to employees in theRemote Access group if they're using atrusted corporate device with a secure password and up-to-date patch level,from any network.
- Only grant access to employees in thePrivileged Access group if the URLpath starts with
/admin.
Before you begin
Before you begin, you'll need the following:
- A IAP-secured app to which you want to add individualor group access.
- User or group names that you want to grant access to.
Set up an access level
To limit access based onIP address orend-user device attributes, create an access level. Some attributes, such as device attributes, require a Chrome Enterprise Premium license. License validation only occurs when you configure access levels and does not affect runtime access. To learn how to create an access level, see theAccess Context Manager guide.IAP uses the access level name to associate it with a IAP-secured app.
The use of scoped policies is not supported by IAP.Access levels must be set in the organizational access policy. For moreinformation, seeCreate an access policy.
Edit the IAM policy
A IAP-secured app has an IAM policy that binds the IAP role to the app.
By adding anIAM conditional binding to the IAM policy, access to your resources are further restricted based onrequest attributes.These request attributes include:
- Access levels
- URL Host/Path
- Date/Time
Note that request values being compared torequest.host andrequest.pathspecified in an IAM conditional binding must be exact. For example,if you restrict access to paths starting with/internal admin,one can bypass the restriction by going to/internal%20admin. For more informationabout hostname and path conditions, seeUse hostname and path conditions.
Add and edit conditional bindings on your IAM policy by followingthe process below.
Console
To add a conditional binding using the Google Cloud console:
Go to theIAP admin page.
Select the checkbox next to the resources that you want to update IAM permissions for.
On the right sideInfo panel, clickAdd principal.
In theNew principal box, enter the principals that you want to assign a role to.
In theSelect a role drop-down list, select theIAP-secured Web App User role and specify access level conditions that the principals will need to meet to access the resource.
- To specify existing access levels, select them from theAccess levels drop-down list. You needto select theIAP-secured Web App User role and have organization levelpermissions to view existing access levels. You must begrantedone of the following roles:
- Access Context Manager Admin
- Access Context Manager Editor
- Access Context Manager Reader
- To create and manage access levels, use theAccess Context Manager.
- To specify existing access levels, select them from theAccess levels drop-down list. You needto select theIAP-secured Web App User role and have organization levelpermissions to view existing access levels. You must begrantedone of the following roles:
If you want to add more roles to the principals, clickAdd another role.
When you're finished adding roles, clickSave.
You have now added a conditional binding to your resource.
To remove a conditional binding:
Go to theIAP admin page.
Select the checkbox next to the resource that you want to remove a principal's IAM role from.
On the right sideInfo panel, underRole / Principal, click the role that you want to remove from the principal.
ClickRemove next to the principal.

On theRemove role from principal dialog that appears, clickRemove. To remove all non-inherited roles from the principal on the selected resource, select the checkbox before clickingRemove.
gcloud
At this time, you can only use the gcloud tool to set project-level conditional bindings.
To set conditional bindings, edit your project'spolicy.yaml file by following the process below:
Open the IAM policy for the app using the following gcloud command:
gcloud iap web get-iam-policy --project=PROJECT_ID > policy.yaml
Edit the
policy.yamlfile to specify the following:- The users and groups you want to apply the IAM condition to.
- The
iap.httpsResourceAccessorrole to grant them access to the resources. The IAM condition.
The following snippet shows an IAM condition with only one attribute specified. This condition grants access to the user and group if theACCESS_LEVEL_NAME access level requirements are met and the resource URL path starts with
/.
bindings:... - members: - group:EXAMPLE_GROUP@GOOGLE.COM - user:EXAMPLE_USER@GOOGLE.COM role: roles/iap.httpsResourceAccessor condition: expression: "accessPolicies/ORGANIZATION_NUMBER/accessLevels/ACCESS_LEVEL_NAME" in request.auth.access_levels&& request.path.startsWith("/") title:CONDITION_TITLE...Bind the policy to the application using the
set-iam-policycommand.gcloud iap web set-iam-policy --project=PROJECT_ID policy.yaml
Your IAM policy now includes a conditional binding.
API
To edit your app'spolicy.json file, follow the process below for your app type. SeeManaging access to IAP-secured resources for more information about using the IAM API to manage access policies.
Before doing the application-specific API steps below, export the following variables:
export PROJECT_NUM=PROJECT_NUMBER export IAP_BASE_URL=https://iap.googleapis.com/v1/projects/${PROJECT_NUM}/iap_web # Replace POLICY_FILE.JSON with the name of JSON file to use for setIamPolicy export JSON_NEW_POLICY=POLICY_FILE.JSONApp Engine
Export the following App Engine variables:
# The APP_ID is usually the project IDexport GAE_APP_ID=APP_IDexport GAE_BASE_URL=${IAP_BASE_URL}/appengine-${GAE_APP_ID}Get the IAM policy for the App Engine app using the
getIamPolicymethod. The empty data bit at the end turns thecurlrequest into POST instead of GET.curl-i-H"Authentication: Bearer$(gcloudauthprint-access-token)"\${GAE_BASE_URL}/:getIamPolicy-d''
Add your IAM conditional binding to the IAM policy JSON file.The following is an example of an edited
policy.jsonfile that binds theiap.httpsResourceAccessorrole to two users, granting them access to the IAP-secured resources. An IAMcondition has been added to grant them access to the resources only if theACCESS_LEVEL_NAME access level requirement is met and the resource URL path starts with/.There can be only one condition per binding.
Example policy.json file{"policy":{"bindings":[{"role":"roles/iap.httpsResourceAccessor","members":["group:EXAMPLE_GROUP@GOOGLE.COM","user:EXAMPLE_USER@GOOGLE.COM"],"condition":{"expression":""accessPolicies/ORGANIZATION_NUMBER/accessLevels/ACCESS_LEVEL_NAME" in request.auth.access_levels && request.path.startsWith("/")","title":"CONDITION_NAME"}}]}}
Set your new
policy.jsonfile using thesetIamPolicymethod.curl -i -H "Authentication: Bearer $(gcloud auth print-access-token)" \${GAE_BASE_URL}:setIamPolicy -d @${JSON_NEW_POLICY}
App Engine services and versions
You can also update the IAM policy of a App Engine service, all versions, or a specific version of a service. To do this for specific version of a service:
- Export the following additional variables.
exportGAE_SERVICE=SERVICE_NAMEexportGAE_VERSION=VERSION_NAME
- Update the exportedGAE_BASE_URL variable.
exportGAE_BASE_URL=${IAP_BASE_URL}/appengine-${GAE_APP_ID}/services/${GAE_SERVICE}/versions/${GAE_VERSION}
- Get and set the IAM policy for the version using the
getIamPolicyandsetIamPolicycommands shown above.
GKE and Compute Engine
Export the project ID of your backend service.
export BACKEND_SERVICE_NAME=BACKEND_SERVICE_NAME
Get the IAM policy for the Compute Engine app using the
getIamPolicymethod. The empty data bit at the end turns thecurlrequest into POST instead of GET.curl -i -H "Authentication: Bearer $(gcloud auth print-access-token)" \ ${IAP_BASE_URL}/compute/services/${BACKEND_SERVICE_NAME}:getIamPolicy \ -d ''Add your IAM conditional binding to the IAM policy JSON file.The following is an example of an edited
policy.jsonfile that binds theiap.httpsResourceAccessorrole to two users, granting them access to the IAP-secured resources. An IAMcondition has been added to grant them access to the resources only if theACCESS_LEVEL_NAME access level requirement is met and the resource URL path starts with/.There can be only one condition per binding.
Example policy.json file{"policy":{"bindings":[{"role":"roles/iap.httpsResourceAccessor","members":["group":EXAMPLE_GROUP@GOOGLE.COM,"user:EXAMPLE_USER@GOOGLE.COM"],"condition":{"expression":""accessPolicies/ORGANIZATION_NUMBER/accessLevels/ACCESS_LEVEL_NAME" in request.auth.access_levels && request.path.startsWith("/")","title":"CONDITION_NAME"}}]}}
Set your new
policy.jsonfile using thesetIamPolicymethod.curl -i -H "Content-Type:application/json" \ -H "Authentication: Bearer $(gcloud auth print-access-token)" \ ${IAP_BASE_URL}/compute/services/${BACKEND_SERVICE_NAME}:setIamPolicy \ -d @${JSON_NEW_POLICY}
Use hostname and path conditions
Access to your app can be secured using the hostname and path of a request URL.For example, therequest.path.startsWith IAM condition can beused to only grant access to employees in thePrivileged Access group ifthe URL path starts with/admin.
For more information about using hostname and path conditions, seerequest attributes.
String normalization
A URL has a hostname and path. For example, the URLhttps://sheets.google.com/create?query=paramhas a hostname ofsheets.google.com and a path of/create.
Backends can interpret hostnames and paths in different ways.To remove ambiguity, IAP normalizes hostname and pathstrings when checking policies.
IAP performs two policychecks when a request has a non-normalized path. If the non-normalizedpath passes the policy check, IAP normalizes the path and asecond policy check is performed. Access is granted if both the non-normalizedand normalized paths pass the policy check.
For example, if a request has the path/internal;some_param/admin,IAP first performs a policycheck on the non-normalized path (/internal). If that passes,IAP performs a second policy check on the normalized path(/internal/admin).
Hostnames
Hostnames are normalized by:
- Removing trailing dots
- Lowercasing characters
- Converting to ASCII
Hostnames that include non-ASCII characters are further normalized withpunycoding. You need to punycode your hostname string for a match to be made.
To punycode your hostname string, use a converterlikePunycoder.
The following are examples of normalized hostnames:
FOO.comis normalized tofoo.comcafé.fris normalized toxn--caf-dma.fr
Paths
Paths are normalized by:
- Removing path params
- Resolving relative paths to their absolute equivalent
A path param includes allcharacters from a; to either the next/ or the end of the path.
Requests that contain..; at thebeginning of a path section are considered invalid.For example,/..;bar/ and/bar/..;/ return theHTTP 400: Bad Requesterror.
The following are examples of normalized paths:
/internal;some_param/adminis normalized to/internal/admin/a/../bis normalized to/b/bar;param1/baz;baz;param2is normalized to/bar/baz
Subdomain endings
A policy set withrequest.host.endsWith("google.com") will match to bothsub_domain.google.com andtestgoogle.com. If your goal is to limit yourpolicy to all subdomains the end withgoogle.com, set your policy torequest.host.endsWith(".google.com").
Note that setting your policy torequest.host.endsWith(".google.com") willmatch withsub_domain.google.com but won't match withgoogle.com due to theadditional..
Cloud Audit Logs and access levels
Enabling Cloud Audit Logs for your IAP-secured project lets you see authorized and unauthorized access requests. View requests and all theaccess levels a requester has met by following the process following:
- Go to the Google Cloud console Logs Explorer for your project.
Go to the logs page - On theresource selector drop-down list, select a resource. IAP-secured HTTPS resources are underApp Engine Application andCompute Engine Backend Service.IAP-secured SSH and TCP resources are underCompute Engine VM instance.
- On thelogs type drop-down list, selectdata_access.
- Thedata_access log type only appears if there was traffic to your resource after you enabled Cloud Audit Logs for IAP.
- Click to expand the date and time of the access you want to review.
- Authorized access has a blue
iicon. - Unauthorized access has an orange
!!icon.
- Authorized access has a blue
- View the access levels the requester has met by clicking to expand sections until you reach
protoPayload>requestMetadata>requestAttributes>auth>accessLevels.
Note that all access levels that a user has met are visible when viewing a request, including access levels that weren't required to access it. Viewing an unauthorized request doesn't indicate what access levels weren't met. This is determined by comparing the conditions on the resource to the access levels visible on the request.
See theCloud Audit Logs guide for more information about logs.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.