This page explains how to create access levels using Access Context Manager and apply them on Identity-Aware Proxy (IAP)-secured resources.
Overview
An access level is a set of attributes assigned to requests based on their origin. Using information such as device type, IP address, and user identity, you can designate what level of access to grant. For example, you might assign a "High_Trust" level to connections from within your corporate network and "Medium_Trust" trust to external devices running approved operating systems.
Device information is gathered and referenced by access levels once you set up Endpoint Verification. Endpoint Verification creates an inventory of all the corporate and personal devices accessing your corporate resources.
An access level is enforced by adding it as an Identity and Access Management (IAM) condition on your IAP-secured resource. IAP lets you apply a fine-grained, resource-level access control model instead of using network-level firewalls. For example, you might specify that while many resources are available to "Medium_Trust," certain more sensitive resources require the "High_Trust" level.
For more information, see the Access Context Manager overview.
Before you begin
Before you begin, you need to do the following:
- Secure a resource with IAP.
- Set up Endpoint Verification. Note that this is only needed if you want to limit access to your resources based on user device information like storage encryption status.
Ensure that you have one of the following roles granted on your project.
- Access Context Manager Admin
- Access Context Manager Editor
Creating an access level
The following process creates an access level.
For this example, assume you want to create an access level that allows a
group of internal auditors to access Google Cloud Observability for a project. All of
the devices for the auditors are assigned IPs on a subnet ranging between
203.0.113.0
and 203.0.113.127
. You also want to ensure their devices are
encrypted. You know there won't be any devices assigned to that subnet other
than those used by the auditors.
Console
Got to the Access Context Manager page in the Google Cloud console.
If you are prompted, select your organization.
At the top of the Access Context Manager page, click New.
In the New Access Level pane, in the Conditions section, click Add attribute and then click Device Policy.
Click the Storage encryption drop-down and select Encrypted. Note that this rule only works once you set up Endpoint Verification on your employees' devices.
Click Add attribute again and select IP Subnetworks.
In the IP Subnetworks box, enter one or more IPv4 or IPv6 ranges formatted as CIDR blocks.
In this example, to limit access to only the auditors, you would enter
203.0.113.0/25
in the IP Subnetworks box.Click Save.
gcloud
Create a .yaml file for an access level that includes one or more IPv4 or IPv6 ranges formatted as CIDR blocks.
In this example, to limit access to only the auditors, you would enter the following into the .yaml file:
- ipSubnetworks: - 203.0.113.0/25 - devicePolicy: allowedEncryptionStatuses - ENCRYPTED
For a list of access level attributes and their YAML format, see Access level attributes. See this example access level YAML file for a comprehensive YAML file of all possible attributes.
Note that the
devicePolicy
rule only works once you set up Endpoint Verification on your employees' devices.Save the file. In this example, the file is named CONDITIONS.yaml.
Create the access level.
gcloud access-context-manager levels create NAME \ --title TITLE \ --basic-level-spec CONDITIONS.yaml \ --policy=POLICY_NAME
Where:
NAME is the unique name for the access level. It must begin with a letter and include only letters, numbers, and underscores.
TITLE is a human-readable title. It must be unique to the policy.
POLICY_NAME is the name of your organization's access policy.
You should see output similar to:
Create request issued for: NAME Waiting for operation [accessPolicies/POLICY_NAME/accessLevels/NAME/create/1521594488380943] to complete...done. Created level NAME.
API
Craft a request body to create an
AccessLevel
resource that includes one or more IPv4 or IPv6 ranges formatted as CIDR blocks and a device policy that requires encrypted storage.In this example, to limit access to only the auditors, you would enter the following into the request body:
{ "name": "NAME", "title": "TITLE", "basic": { "conditions": [ { "ipSubnetworks": [ "203.0.113.0/25" ] }, { "devicePolicy": [ "allowedEncryptionStatuses": [ "ENCRYPTED" ] ] } ] } }
Where:
NAME is the unique name for the access level. It must begin with a letter and include only letters, numbers, and underscores.
TITLE is a human-readable title. It must be unique to the policy.
Create the access level by calling
accessLevels.create
.POST https://accesscontextmanager.googleapis.com/v1/accessPolicies/POLICY_NAME/accessLevels
Where:
- POLICY_NAME is the name of your organization's access policy.
Applying an access level
An IAP-secured resource has an IAM policy that binds the IAP role to the resource.
By adding an IAM conditional binding to the IAM policy, access to your resources are further restricted based on request attributes. These request attributes include:
- Access levels
- URL Host/Path
- Date/Time
Note that request values being compared to request.host
and request.path
specified 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
. See
Using hostname and path conditions
for more information.
The following steps show how to add your access level to a IAP-secured resource by updating its IAM policy.
Console
Go to the IAP admin page.
Select the checkbox next to the resources that you want to update IAM permissions for.
On the right side Info panel, click Add principal.
In the New principal box, enter the principals that you want to assign a role to.
In the Select a role drop-down list, select the IAP-secured Web App User role.
To specify existing access levels, select them from the Access levels drop-down list. You need to select the IAP-secured Web App User role and have organization level permissions to view existing access levels.
When you apply multiple access levels to a resource, users are granted access to the resource when they meet the conditions specified in at least one of the access levels you select (it`s a logical OR of the access levels in the list). If you want users to meet the conditions in more than one access level (a logical AND of access levels), create an access level that contains multiple access levels.
If you want to add more roles to the principals, click Add another role.
When you're finished adding roles, click Save.
gcloud
Currently, you can only use the gcloud CLI to set project-level conditional bindings.
To set conditional bindings, edit your project's policy.yaml
file by
following the process below:
Open the IAM policy for the app using the following gcloud command:
gcloud projects get-iam-policy PROJECT_ID > policy.yaml
Edit the
policy.yaml
file to specify the following:- The users and groups you want to apply the IAM condition to.
- The
iap.httpsResourceAccessor
role to grant them access to the resources. - The IAM condition with your access level.
The following condition grants access to the user and group if the ACCESS_LEVEL_NAME access level requirements are met and the resource URL path starts with
/
.... - 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 app using the
set-iam-policy
command.gcloud projects set-iam-policy PROJECT_ID policy.yaml
API
To edit your app's policy.json
file, follow the process below for your
app type. See Managing access to IAP-secured resources
for more information about using the IAM API to manage
access policies.
Before you complete the app-specific API steps below, export the following variables:
export PROJECT_NUM=PROJECT_NUMBER export IAP_BASE_URL=https://iap.googleapis.com/v1beta1/projects/${PROJECT_NUMBER}/iap_web # Replace POLICY_FILE.JSON with the name of JSON file to use for setIamPolicy export JSON_NEW_POLICY=POLICY_FILE.JSON
App Engine
Export the following App Engine variables:
# The APP_ID is usually the project ID export GAE_APP_ID=APP_ID export GAE_BASE_URL=${IAP_BASE_URL}/appengine-${GAE_APP_ID}
Get the IAM policy for the App Engine app using the
getIamPolicy
method. The empty data bit at the end turns thecurl
request into POST instead of GET.curl -i -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -d '' ${GAE_BASE_URL}/:getIamPolicy
Add your IAM conditional binding to the IAM policy JSON file. The following is an example of an edited
policy.json
file that binds theiap.httpsResourceAccessor
role to two users, granting them access to the Chrome Enterprise Premium- secured resources. An IAM condition has been added to grant them access to the resources only if the ACCESS_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.json
file using thesetIamPolicy
method.curl -i -H "Authorization: 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 a specific version of a service:
- Export the following additional variables.
export GAE_SERVICE=SERVICE_NAME export GAE_VERSION=VERSION_NAME
- Update the exported GAE_BASE_URL variable.
export GAE_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
getIamPolicy
andsetIamPolicy
commands 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
getIamPolicy
method. The empty data bit at the end turns thecurl
request into POST instead of GET.curl -i -H "Authorization: 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.json
file that binds theiap.httpsResourceAccessor
role to two users, granting them access to the Chrome Enterprise Premium- secured resources. An IAM condition has been added to grant them access to the resources only if the ACCESS_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.json
file using thesetIamPolicy
method.curl -i -H "Content-Type:application/json" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ ${IAP_BASE_URL}/compute/services/${BACKEND_SERVICE_NAME}:setIamPolicy \ -d @${JSON_NEW_POLICY}