Secure access to SaaS applications

This page guides you through the process of securing your SaaS applications through the Chrome Enterprise Premium secure gateway.

A Chrome Enterprise Premium secure gateway functions as a forward proxy, enforcing a zero trust access framework and delivering granular, context-aware control over who accesses your SaaS applications.

How securing access to SaaS applications works

Following is a high level overview of how a secure gateway protects your SaaS applications:

  1. Client-side browser settings route application traffic through a secure gateway proxy.
  2. The secure gateway checks context-aware access policies to authorize client (user and device) access.
  3. If client access is allowed, the gateway forwards traffic to the application using unique source IP addresses assigned to that gateway and Google Cloud region. These assigned IP addresses are reserved exclusively for the gateway that you create and cannot be used by other users or gateways. To control access, you can add these dedicated source IP addresses to an allowlist in your SaaS application.

Before you begin

Before setting up the secure gateway, verify that you have the following:

Limitations

A Chrome Enterprise Premium secure gateway has the following limitation: A secure gateway does not support SaaS applications that allow only IPv6 connectivity.

Set up your shell environment

To streamline the setup process and interact with the secure gateway APIs, define the following environment variables in your working shell.

  • General parameters

    API="beyondcorp.googleapis.com"
    API_VERSION=v1
    PROJECT_ID=MY_PROJECT_ID
    APPLICATION_ID=MY_APPLICATION_ID
    APPLICATION_DISPLAY_NAME="MY_APPLICATION_DISPLAY_NAME"
    HOST_NAME=MY_HOST_NAME

    Replace the following:

    • MY_PROJECT_ID: The ID of the project where the secure gateway is created.
    • MY_APPLICATION_ID: The ID of your application, such as github. The name can be up to 63 characters, and can contain lowercase letters, numbers, and hyphens. The first character must be a letter, and the last character can be a letter or number.
    • MY_APPLICATION_DISPLAY_NAME: The human-readable name to display.
    • MY_HOST_NAME: The hostname of your application. For example, github.com. The hostname can be up to 253 characters long, and must adhere to one of the following formats:

      • A valid IPv4 address
      • A valid IPv6 address
      • A valid DNS name
      • An asterisk (*)
      • An asterisk (*) followed by a valid DNS name
  • Secure gateway parameters

    SECURITY_GATEWAY_ID=MY_SECURITY_GATEWAY_ID
    SECURITY_GATEWAY_DISPLAY_NAME="MY_SECURITY_GATEWAY_DISPLAY_NAME"

    Replace the following:

    • MY_SECURITY_GATEWAY_ID: The ID of the secure gateway. The ID can be up to 63 characters, and can contain lowercase letters, numbers, and hyphens. The first character should be a letter, and the last character can be a letter or number.
    • MY_SECURITY_GATEWAY_DISPLAY_NAME: The human-readable name of the secure gateway. The name can be up to 63 characters long and can only contain printable characters.

Create a secure gateway

A Chrome Enterprise Premium secure gateway is a fundamental building block for establishing secure connections to your applications. It allocates a dedicated project and network, providing isolation and security.

To create a secure gateway resource, use one of the following methods.

gcloud

Run the following command. For the --hubs flag, specify one or more regions from the following list.

gcloud beta beyondcorp security-gateways create ${SECURITY_GATEWAY_ID} \
  --project=${PROJECT_ID} \
  --location=global \
  --display-name="MY_SECURITY_GATEWAY_DISPLAY_NAME" \
  --hubs=us-central1
      

REST

Call the Create API method with the gateway details in the request body. For the hubs object, specify one or more regions from the following list.

curl \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-X POST \
-d '{ "display_name": "MY_SECURITY_GATEWAY_DISPLAY_NAME", "hubs": { "us-central1": {} } }' \
"https://${API}/${API_VERSION}/projects/${PROJECT_ID}/locations/global/securityGateways?security_gateway_id=${SECURITY_GATEWAY_ID}"
      

The hubs represents the regional resources required for enabling egress connectivity to the target application. You can have one hub for each region, and each hub provides two IP addresses. You can specify the following regions:

  • africa-south1
  • asia-east1
  • asia-south1
  • asia-south2
  • asia-southeast1
  • europe-central2
  • europe-north1
  • europe-southwest1
  • europe-west1
  • europe-west2
  • europe-west3
  • europe-west4
  • europe-west8
  • europe-west9
  • northamerica-northeast1
  • northamerica-northeast2
  • northamerica-south1
  • southamerica-east1
  • southamerica-west1
  • us-central1
  • us-east1
  • us-east4
  • us-east5
  • us-west1

Configure a SaaS application

After you create a secure gateway, you can configure your SaaS applications to use the secure gateway for secure access.

  1. Get the IP addresses allocated by the secure gateway for each hub. Two IP addresses are allocated for a region.

    gcloud

    gcloud beta beyondcorp security-gateways describe ${SECURITY_GATEWAY_ID} \
    --project=${PROJECT_ID} \
    --location=global
        

    REST

    curl \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    "https://${API}/${API_VERSION}/projects/${PROJECT_ID}/locations/global/securityGateways/${SECURITY_GATEWAY_ID}"
        

    The following is a sample GET response of a secure gateway with hubs. In the example, hubs are created in the us-central1 and us-east1 regions, and all of the IP addresses returned in the response must be allowed in the SaaS application.

    gcloud

    createTime: 'CREATE_TIME'
    displayName: My security gateway
    hubs:
      us-central1:
        internetGateway:
          assignedIps:
          - IP_ADDRESS_1
          - IP_ADDRESS_2
      us-east1:
        internetGateway:
          assignedIps:
          - IP_ADDRESS_1
          - IP_ADDRESS_2
    name: projects/${PROJECT_ID}/locations/global/securityGateways/${SECURITY_GATEWAY_ID}
    state: RUNNING
    updateTime: 'UPDATE_TIME'
        

    REST

    {
      "securityGateways": [
        {
          "name": "projects/${PROJECT_ID}/locations/global/securityGateways/${SECURITY_GATEWAY_ID}",
          "createTime": "CREATE_TIME",
          "updateTime": "UPDATE_TIME",
          "displayName": "My security gateway",
          "state": "RUNNING",
          "hubs": {
            "us-central1": {
              "internetGateway": {
                "assignedIps": [
                  "IP_ADDRESS_1",
                  "IP_ADDRESS_2",
                ]
              }
            },
            "us-east1": {
              "internetGateway": {
                "assignedIps": [
                  "IP_ADDRESS_1",
                  "IP_ADDRESS_2",
                ]
              }
            }
          }
        }
      ]
    }
        
  2. Add the IP addresses to the IP allowlist of your SaaS application. For example, for a GitHub application, you can follow this guide: Managing allowed IP addresses for your organization.

Create an application resource

The following information guides you through the process of setting up and configuring a secure gateway application resource.

Create a secure gateway application resource in Google Cloud

The Google Cloud application resource is a sub-resource of the secure gateway resource. Create an application resource by calling the Create API.

gcloud

gcloud beta beyondcorp security-gateways applications create ${APPLICATION_ID} \
  --project=${PROJECT_ID} \
  --security-gateway=${SECURITY_GATEWAY_ID} \
  --location=global \
  --display-name="${APPLICATION_DISPLAY_NAME}" \
  --endpoint-matchers="hostname=${HOST_NAME},ports=[443]"
      

REST

curl \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-X POST \
-d "{ \"display_name\": \"${APPLICATION_DISPLAY_NAME}\", \"endpoint_matchers\": [{hostname: \"${HOST_NAME}\", ports: [443]}] }" \
"https://${API}/${API_VERSION}/projects/${PROJECT_ID}/locations/global/securityGateways/${SECURITY_GATEWAY_ID}/applications?application_id=${APPLICATION_ID}"
      

Configure Google Chrome proxy mode

To route traffic for the application resource through the secure gateway, configure Chrome by applying a PAC file in the Chrome settings in the Google Admin console.

  1. Create or update a PAC file.

    • If you're creating your first application, create a pac_config.js file using the following example PAC file.

    • If you are creating a second or subsequent application, update your existing pac_config.js file and add the domains of your new application to the sites array, as shown in the following example PAC file.

    function FindProxyForURL(url, host) {
     const PROXY = "HTTPS ingress.cloudproxy.app:443";
     const sites = ["MY_HOST_NAME"];
    
     for (const site of sites) {
       if (shExpMatch(url, 'https://' + site + '/*') || shExpMatch(url, '*.' + site + '/*')) {
         return PROXY;
       }
     }
    return 'DIRECT';
    }

    If you are using an existing PAC file that is not specific to a secure gateway, merge the PAC files by adding the domains of your application to the sites array.

  2. Upload the file so that it is publicly downloadable. For example, you can upload the file to Cloud Storage, and make the file publicly downloadable by granting all users the Storage Object User role on the bucket.

  3. To verify that the uploaded file is always the latest version, you can adjust its caching behavior by setting the Cache-Control header to no-cache. This setting prevents browsers and intermediate servers from storing a copy of the file, so that Chrome always downloads the most recent version.

    For more information about Cache-Control and how it affects browser caching, see Cache-Control header.

  4. Copy the public URL of the uploaded file.

Update the proxy mode settings

  1. Go to the Google Admin console.
  2. Click Devices -> Chrome -> Settings.
  3. Select an organization unit or group, and then click Proxy mode.
  4. In the Proxy mode page, select Always use the proxy auto-config specified below and enter the URL of the PAC file from Cloud Storage.

Configure an access policy

You can apply an access policy to control access at either the secure gateway level, which affects all associated applications, or at the individual application level for more granular control.

Safely update an access policy

The setIamPolicy command replaces the entire existing policy with the one you provide. To avoid accidentally removing existing permissions, we recommend that you follow a "read-modify-write" pattern. This ensures that you are only adding to the existing policy, not overwriting it.

  1. Read: First, get the current access policy.

  2. Modify: Edit the policy file locally to add or change permissions.

  3. Write: Apply your updated policy file.

Get the current policy

Retrieve the current policy before making any changes.

The etag field in the policy acts as a version identifier. It prevents conflicting updates if multiple administrators make changes simultaneously.

The following command retrieves the policy and saves it to a file named policy.json.

curl \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://${API}/${API_VERSION}/projects/${PROJECT_ID}/locations/global/securityGateways/${SECURITY_GATEWAY_ID}/applications/${APPLICATION_ID}:getIamPolicy" > policy.json

After you run the command, a policy.json file that contains the current policy is created.

Modify the policy file

Open the policy.json file in a text editor. To grant a group access to use the secure gateway, add the group to the members list for the roles/beyondcorp.securityGatewayUser role.

Your policy.json should be similar to the following example:

{
  "policy": {
    "version": 3,
    "bindings": [
      {
        "role": "roles/beyondcorp.securityGatewayUser",
        "members": [
          "group:existing-group@example.com"
        ]
      }
    ],
    "etag": "BwXN8_d-bOM="
  }
}

To add a new group, add a new entry to the members array. Include a comma after the preceding entry.

The following example adds new-group@example.com:

{
  "policy": {
    "version": 3,
    "bindings": [
      {
        "role": "roles/beyondcorp.securityGatewayUser",
        "members": [
          "group:existing-group@example.com",
          "group:new-group@example.com"
        ]
      }
    ],
    "etag": "BwXN8_d-bOM="
  }
}

You can also add other types of members, such as serviceAccount, user, group, principal, and principalSet, in policy bindings. See IAM principals for more information.

Apply the updated policy

After editing and saving your policy.json file, apply it to the resource using the setIamPolicy command. This command uses the etag from your file to ensure that you update the correct version.

jq '{policy: .}' policy.json | curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -d @- \
    "https://${API}/${API_VERSION}/projects/${PROJECT_ID}/locations/global/securityGateways/${SECURITY_GATEWAY_ID}/applications/${APPLICATION_ID}:setIamPolicy"

Add a conditional access policy

You can also set access policies with conditions. Conditions specify requirements, such as a user's IP address originating from a specific location.

The following example shows a policy that grants access only if the source IP address is within a specified access level:

{
  "policy": {
    "version": 3,
    "bindings": [
      {
        "role": "roles/beyondcorp.securityGatewayUser",
        "members": [
          "group:group@example.com"
        ],
        "condition": {
          "expression": "request.auth.access_levels.contains('accessPolicies/1234567890/accessLevels/in_us')",
          "title": "Source IP must be in US"
        }
      }
    ],
    "etag": "BwXN8_d-bOM="
  }
}

To apply this policy, follow the steps steps described earlier.

Install the Chrome Enterprise Premium extension

The Chrome Enterprise Premium extension is an integral part of a secure gateway and helps with authentication. Install the extension for all of the users of the secure gateway. For information about deploying the extension, see View and configure apps and extensions.

  1. Go to the Google Admin console.
  2. Click Chrome browser -> Apps & Extensions.
  3. Click the Users & browsers tab.
  4. To add a Chrome extension, click the + button.
  5. Search for ekajlcmdfcigmdbphhifahdfjbkciflj, and then force install to all users in the organization unit or group.
  6. Click the installed extension, and then go to the Policy for extensions field and provide the following JSON value:

    {
     "securityGateway": {
       "Value": {
         "authentication": {},
         "context": { "resource": "projects/MY_PROJECT_ID/locations/global/securityGateways/MY_SECURITY_GATEWAY_ID" }
       }
     }
    }

End user experience

When the setup is complete, end users accessing the protected SaaS application are granted or denied access based on the access policy applied to the application.

Accessing the application in Chrome

The Chrome Enterprise Premium extension is required to direct traffic through the secure gateway. The extension handles the authentication between the user and the secure gateway. The extension is automatically installed through the domain policy.

When users access the SaaS application that you configured, their traffic goes through the secure gateway, which checks if they satisfy the access policy. If the users pass the access policy checks, they are granted access to the application.

When browser access to the application is rejected by the authorization policy, users receive an Access denied message.

What's next