Configure Context-Aware Access for service accounts

This guide describes how you can set up Context-Aware Access to help secure service account access to Google Cloud APIs, based on access levels that you define.

Limitations

The following limitations apply to Context-Aware Access policies for service accounts:

  • Network-based or IP address-based attributes cannot be used for service account bindings if the service account will be used for workflow executions and Cloud Scheduler.

  • Connections to private GKE clusters, using kubectl, and to Cloud SQL, using Auth Proxy, cannot be blocked by Context-Aware Access policies.

  • If an access level that is bound to a service account contains unsupported attributes, such as Device attributes, then API access is denied.

  • Scoped access levels aren't supported for service accounts.

If you use Cloud Build and Cloud Run, we recommend that you use the following built-in VPC features:

Before you begin

  1. Make sure that you have a Google Cloud organization and at least one Google Cloud project.
  2. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  3. Install the Google Cloud CLI.

  4. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  5. To initialize the gcloud CLI, run the following command:

    gcloud init
  6. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  7. Verify that billing is enabled for your Google Cloud project.

  8. Install the Google Cloud CLI.

  9. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  10. To initialize the gcloud CLI, run the following command:

    gcloud init
  11. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Update Google Cloud CLI components:
    gcloud components update --quiet
  14. Create a service account in your project if you don't already have one. This service account is the target of the Context-Aware Access policy.

Required roles

This section describes the Identity and Access Management (IAM) roles that are required to use Context-Aware Access.

Project-level roles

To get the permission that you need to at the project level, ask your administrator to grant you the Service Account Admin (roles/iam.serviceAccountAdmin) IAM role on the user account or service account. For more information about granting roles, see Manage access to projects, folders, and organizations.

This predefined role contains the the required permissions permission, which is required to at the project level.

You might also be able to get this permission with custom roles or other predefined roles.

Organization-level roles

To get the permission that you need to at the organization level, ask your administrator to grant you the following IAM roles on user account or service account:

For more information about granting roles, see Manage access to projects, folders, and organizations.

This predefined role contains the the required permissions permission, which is required to at the organization level.

You might also be able to get this permission with custom roles or other predefined roles.

Bind Context-Aware Access policies to different resource levels

You can bind Context-Aware Access policies with the same enforcement mode to resources that are at different levels of the resource hierarchy. When a resource attempts access, Context-Aware Access uses the policy that is bound to that resource before it attempts to use a policy that is bound to a higher-level resource.

For example, you can bind an enforcement-mode policy directly to a service account and a different enforcement-mode policy to the project that contains the service account. When the service account attempts to access resources, Context-Aware Access evaluates the policy that is bound to the service account. For other service accounts in the project that don't have policies bound to them, Context-Aware Access evaluates the enforcement-mode policy that is bound to the project. The same is true if the enforcement mode is set to dry run for both the project-level policy and the service account-level policy.

You can use multiple policies to incrementally and selectively deploy policies—for example, you can do the following:

  1. Bind a policy in dry-run mode at the project level and make sure that it's working as you expect by checking for access denied events in Cloud Audit Logs.
  2. Bind the policy in enforcement mode only to specific service accounts.
  3. Bind the policy in enforcement mode at the project level, and bind a less restrictive, enforcement-mode policy to specific service accounts as needed.

Access level attributes for service accounts

This section lists the access levels that are supported for service accounts.

The following attributes are supported for service accounts:

  • IP subnetworks, which are based on the public IP address.
  • VPC networks, which are based on the private IP address.
  • Geolocation, which is based on the public IP address.

    When the service account makes any request to Google Cloud APIs, the request is evaluated by Context-Aware Access, and the IP address of the request is compared to the IP addresses specified in the Context-Aware Access policy. If the IP addresses match, the API call is allowed. If the IP address doesn't match, the API call is denied.

  • A custom access level with a Common Expression Language (CEL) expression. The expression must evaluate to true to allow access and false to deny access.

    The following CEL expression is useful for restricting access by service accounts.

    The expression evaluates to true if the request originated from one or more specified project numbers:

        expression: "originatesFromProjects(origin, [PROJECT_NUMBER, ...])"
        

    originatesFromProjects checks whether the request comes from a network that is associated with the specified project and whether the request comes from a private IP address.

  • Time of day, which is based on the time and date of the request in a specified time zone.

    For more information, see Configuring time and day access conditions.

Create an access level

This section describes how to create an access level within your organization. Access levels define the conditions under which access is permitted.

  1. Follow the instructions to Create a basic access level or Create a custom access level.

  2. Note the full name of the access level, which has the format: accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME.

Create an access binding

Bind the access level to the selected service account. Doing so enforces the conditions defined in the access level. You can bind the access level to a single service account or all service accounts within a project.

Bind the access level to a specific service account

This section describes how to bind the access level to a specific service account.

gcloud

Bind the access level to a service account using the gcloud CLI.

gcloud access-context-manager cloud-bindings create \
    --organization=ORGANIZATION_ID \
    --service-account=SERVICE_ACCOUNT_NAME@SERVICE_ACCOUNT_PROJECT_ID.iam.gserviceaccount.com \
    --level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

Replace the following:

  • ORGANIZATION_ID: your Google Cloud organization ID
  • SERVICE_ACCOUNT_NAME: the name, not the email, of the target service account
  • SERVICE_ACCOUNT_PROJECT_ID: the ID of the project that contains the target service account
  • POLICY_ID: the ID of the Access Context Manager access policy
  • ACCESS_LEVEL_NAME: the name of the access level that you created

    To use Context-Aware Access without enforcing the access level and disallowing access, you can bind the access level in dry-run mode.

REST API

To bind the access level to a specific service account using the REST API, run the following command:

  1. Create a request.json file with the following content:

    {
      "principal": {
        "serviceAccount": "SERVICE_ACCOUNT_NAME@SERVICE_ACCOUNT_PROJECT_ID.iam.gserviceaccount.com"
      },
      "accessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
    }
    

    Replace the following:

    • SERVICE_ACCOUNT_NAME: the name, not the email, of the target service account

    • SERVICE_ACCOUNT_PROJECT_ID: the ID of the project that contains the target service account

    • POLICY_ID: the ID of the Access Context Manager access policy

    • ACCESS_LEVEL_NAME: the name of the access level that you created

  2. Run the following command:

    curl -H "X-Goog-User-Project: PROJECT_ID" -X POST \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" \
      -d @request.json \
      "https://accesscontextmanager.googleapis.com/v1/organizations/ORGANIZATION_ID/gcpUserAccessBindings"
    

    Replace the following:

    • PROJECT_ID: the ID of the project that you are using to make the API calls

    • ORGANIZATION_ID: your Google Cloud organization ID.

Bind the access level to all service accounts in a project

This section describes how to bind the access level to all of the service accounts in a project.

gcloud

To bind the access level to all of the service accounts in a project using the gcloud CLI, run the following command:

gcloud access-context-manager cloud-bindings create \
  --organization=ORGANIZATION_ID \
  --service-account-project-number=PROJECT_NUMBER \
  --level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

Replace the following:

  • ORGANIZATION_ID: your Google Cloud organization ID
  • PROJECT_NUMBER: the project number of the project that contains all of the service accounts that you want to bind access to
  • POLICY_ID: the ID of the Access Context Manager access policy
  • ACCESS_LEVEL_NAME: the name of the access level that you created.

REST API

To bind the access level to all of the service accounts in a project using the REST API, do the following:

  1. Create a request.json file with the following content:

    {
      "principal": {
        "serviceAccountProjectNumber": "PROJECT_NUMBER"
      },
      "accessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
    }
    

    Replace the following:

    • PROJECT_NUMBER: the project number of the project that contains all of the service accounts that you want to bind access to
    • POLICY_ID: the ID of the Access Context Manager access policy
    • ACCESS_LEVEL_NAME: the name of the access level that you created.
  2. Run the following command:

    curl -H "X-Goog-User-Project: PROJECT_ID" -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://accesscontextmanager.googleapis.com/v1/organizations/ORGANIZATION_ID/gcpUserAccessBindings"
    

    Replace the following:

    • PROJECT_ID: the ID of the project you are using to make the API calls
    • ORGANIZATION_ID: your Google Cloud organization ID

To use Context-Aware Access without enforcing the access level and denying access, you can bind the access level in dry-run mode.

The API response for the create binding operation includes the name of the binding, which contains the unique binding ID.

Use dry-run mode

You can bind the access level in dry-run mode. When you use dry-run mode, your service accounts can continue to access resources without enforcement. However, if your service accounts attempt access that violates the access level, Context-Aware Access logs the violation to Cloud Audit Logs.

Bind the access level in dry-run mode

gcloud

To bind the access level in dry-run mode, replace the --level parameter with --dry-run-level, formatted as follows:

--dry-run-level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

REST API

To bind the access level in dry-run mode, create the