Advanced Access control using Google Cloud IAM conditions for Google Cloud IAP / Beyondcorp Enterprise enabled applications

Iamsri
Google Cloud - Community
6 min readOct 22, 2023

Google Cloud Identity-Aware Proxy (IAP) is a service that helps you control access to your web applications hosted on Google Cloud or other Clouds. IAP uses Google Cloud Identity and Access Management (IAM) to authenticate and authorize users. IAP can be used to restrict access to applications based on the user’s IP address and Geo location. When combined with Beyondcorp Enterprise, customers can use additional device level attributes such as, is the user using, a company-owned device, a managed Chrome browser and/or managed Chrome profile, device encryption status, among many others.

This blog post will show you how to use Google Cloud IAM conditions to restrict access to specific parts (based on URL path) of your IAP-enabled application.

high level request flow

Customer use case

Let’s say that you have a web application with the following paths under one hostname:

  • / — The home page of your application.
  • /admin — A restricted section of your application that is only accessible to administrators.
  • /hr/payroll — A restricted section of your application that is only accessible to human resources employees.

You want IAP to restrict access to the /admin and /hr/payroll sections of your application to application admins and Payroll admins respectively, and ensure they are using a company-owned / managed device, while allowing the rest of the authenticated employees access to other general parts of the application.

use case illustration

Prerequisites

  1. Web application deployed behind Google Cloud application loadbalancer. Refer to this for sample deployment

How to implement

Let’s break down the process into steps and use `gcloud` command-line examples to demonstrate how to set up access control using IAM conditions, specifically using Request attributes to achieve the granular level of access as defined in our use case.

  1. Create access levels in the Access Context Manager

Through Access Context Manager, access levels are created to define access rules. Access levels applied on your resources with IAM Conditions enforce fine-grained access control based on a variety of attributes.

Access levels restrict access based on the following attributes:

When you create a device-based access level, Access Context Manager references the inventory of devices created by Endpoint Verification.

Now, lets create an access level for our usecase defined above using gcloud. The steps involved are as follows.

  1. Get list of access policies in your Organization.
  2. Copy the policy number for the “default policy”
  3. Set the default policy in gcloud
  4. Create access levels.
gcloud access-context-manager policies list --organization <Organization_ID>

Output woud look similar to this
NAME: 111122223333
ORGANIZATION: 123456789012
SCOPES:
TITLE: default policy
ETAG: e7a35a6f8b481bb6

If your organization doesn’t have an access policy, you should create one
at this time.

gcloud config set access_context_manager/policy <Policy>

Policy is a numerical value, which is 111122223333 in the above sample output.
In this post we are using the default policy which is applicable to
Organization.

Create a conditions file in YAML format and modify the IP address as desired. It has to be a non RFC 1918 IP address. Lets save this file acl-conditions.yaml. The below basic conditions file has 2 conditions it can check for, 1. is the device a Corp owned 2. Source IP address.

- devicePolicy:
requireCorpOwned: true
ipSubnetworks:
- 1.1.1.0/24

Now, lets create an access level using the gcloud command below.

gcloud access-context-manager levels create <Unique_acl_Name> \
--title <Title for your access level> \
--basic-level-spec acl-conditions.yaml --combine-function=AND

Unique_Name - Can have letters, digits and underscore (immutable).
Title - a String, cannot be more than 50 characters.
Combine-function can be AND | OR default is AND

For more examples of conditions that can be used when creating access level, please refer to this link, https://cloud.google.com/access-context-manager/docs/create-basic-access-level#example_implementations

Here, I have added a screenshot for how you can create an access level with similar condition using Cloud console.

2. Enable IAP for your application

Although not strictly necessary, it makes sense to create the desired access levels and have a well defined IAM policy binding (next step) before enabling IAP for your application. Moments after enabling IAP for the appropriate backend services, users will be prompted to login using their Google account. And each request will be continuously evaluated against the IAM policy bindings

gcloud compute backend-services update BACKEND_SERVICE_NAME \
--iap=enabled,oauth2-client-id=ID,oauth2-client-secret=SECRET \
--global

3. Create IAM policy bindings

Once you have created your access levels, you need to create IAM policy bindings that use the HTTP path and the access level.

To create an IAM policy binding, you can use the following gcloud command:

  1. Create and save the policy in an YAML file, lets call it iap-iam-poilcy.yaml

In the policy example below, we are allowing access to the IAP enabled application to multiple google groups:

bindings:
- condition:
expression: (request.path.startsWith("/") ) &&
(!request.path.startsWith("/admin") &&
!request.path.startsWith("/hr/payroll"))
title: Deny admin paths
description: allows all path except for /admin and /hr/payroll
members:
- group:all-employees@example.com
role: roles/iap.httpsResourceAccessor
- condition:
expression: ("accessPolicies/<policy#_from_step1>/accessLevels/<acl_name>"
in request.auth.access_levels) &&
(request.path.startsWith("/admin"))
title: Require Corp owned devices for admin
description: requires access from corp network and corp owned devices
members:
- group:admins@example.com
role: roles/iap.httpsResourceAccessor
- condition:
expression: ("accessPolicies/<policy#_from_step1>/accessLevels/<acl_name>"
in request.auth.access_levels) &&
(request.path.startsWith("/hr/payroll"))
title: Require Corp owned devices for payroll
description: requires access from corp network and corp owned devices
members:
- group:hr-admins@example.com
role: roles/iap.httpsResourceAccessor
- condition:
description: Does not grant access after Jan 1st 2024
expression: (request.time < timestamp('2024-01-01T00:00:00.000Z')) &&
(request.path.startsWith("/") &&
!request.path.startsWith("/admin") &&
!request.path.startsWith("/hr/payroll"))
title: expirable access for vendors
members:
- group:vendors@example.com
role: roles/iap.httpsResourceAccessor
- condition:
expression: ("accessPolicies/<policy#_from_step1>/accessLevels/<acl_name>"
in request.auth.access_levels)
title: Corp owned devices for IAP administrator
description: requires access from corp network and corp owned devices
members:
- group:iap-admins@example.com
role: roles/iap.settingsAdmin

2. Apply the IAM policy to the IAP resource using the command below

gcloud iap web set-iam-policy iap-iam-policy.yaml  \
--resource-type=backend-services \
--service=<loadbalancer_backend_service_name>

This command will create an IAM policy binding that grants the iap.httpsResourceAccessor role to the user account for all parts of the application except for the requests that start with the /admin and /hr/payroll path in the URL.

You can also create IAM policy bindings for multiple paths. For example, to create an IAM policy binding that grants the iap.httpsResourceAccessor role to the my-service-account service account for requests that start with the /admin and /hr/payroll paths, you can use the following command:

Note: You cannot use conditions when you grant basic roles, including Owner (roles/owner), Editor (roles/editor), and Viewer (roles/viewer). Also, you cannot use conditions when you grant roles to all users (allUsers) or all authenticated users (allAuthenticatedUsers). More here https://cloud.google.com/iam/docs/conditions-overview

You can use the command below to see IAM policy attached to the IAP enabled backend service.

gcloud iap web get-iam-policy --resource-type=backend-services \
--service=file-upload-be-svc-1

Testing your access controls

Once you have complete all the above steps, you can test your access controls by making requests to the different parts of your application.

Conclusion

Securing your web applications is crucial, especially when dealing with sensitive areas within those applications. Google Cloud IAP, combined with Beyondcorp Enterprise, while leveraging IAM conditions, provides a powerful and flexible way to restrict access based on various criteria, such as device attributes, user location and request attributes.

Thanks to my colleague Trever Jackson for his assistance in getting this blog out!

--

--