This guide describes how you can set up Context-Aware Access to help secure service account access to Cloud de Confiance by S3NS 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
Deviceattributes, 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:
For Cloud Run, use serverless VPC access.
For Cloud Build, use private pools.
Before you begin
- Make sure that you have a Cloud de Confiance organization and at least one Cloud de Confiance project.
-
Install the Google Cloud CLI.
-
Configure the gcloud CLI to use your federated identity.
For more information, see Sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init -
Create or select a Cloud de Confiance 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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Create a Cloud de Confiance project:
gcloud projects create PROJECT_ID
Replace
PROJECT_IDwith a name for the Cloud de Confiance project you are creating. -
Select the Cloud de Confiance project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_IDwith your Cloud de Confiance project name.
-
Verify that billing is enabled for your Cloud de Confiance project.
- Update Google Cloud CLI components:
gcloud components update --quiet
- Create a service account in your project if you don't already have one. This service account is the target of the 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:
- Cloud Access Binding Admin (
roles/accesscontextmanager.gcpAccessAdmin) - Access Context Manager Admin (
roles/accesscontextmanager.policyAdmin)
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 access policies to different resource levels
You can bind 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 access 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 access 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 access policies to incrementally and selectively deploy access policies—for example, you can do the following:
- Bind an access 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.
- Bind the access policy in enforcement mode only to specific service accounts.
- Bind the access policy in enforcement mode at the project level, and bind a less restrictive, enforcement-mode access 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 Cloud de Confiance 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
trueto allow access andfalseto deny access.The following CEL expression is useful for restricting access by service accounts.
The expression evaluates to
trueif the request originated from one or more specified project numbers:expression: "originatesFromProjects(origin, [PROJECT_NUMBER, ...])"originatesFromProjectschecks 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.
Follow the instructions to Create a basic access level or Create a custom access level.
Note the full name of the access policy, 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.s3ns.iam.gserviceaccount.com \
--level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME
Replace the following:
ORGANIZATION_ID: your Cloud de Confiance organization IDSERVICE_ACCOUNT_NAME: the name, not the email, of the target service accountSERVICE_ACCOUNT_PROJECT_ID: the ID of the project that contains the target service accountPOLICY_ID: the ID of the access policyACCESS_LEVEL_NAME: the name of the access level that you createdTo 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:
Create a
request.jsonfile with the following content:{ "principal": { "serviceAccount": "SERVICE_ACCOUNT_NAME@SERVICE_ACCOUNT_PROJECT_ID.s3ns.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 accountSERVICE_ACCOUNT_PROJECT_ID: the ID of the project that contains the target service accountPOLICY_ID: the ID of the access policyACCESS_LEVEL_NAME: the name of the access level that you created
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 callsORGANIZATION_ID: your Cloud de Confiance 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 Cloud de Confiance organization IDPROJECT_NUMBER: the project number of the project that contains all of the service accounts that you want to bind access toPOLICY_ID: the ID of the access policyACCESS_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:
Create a
request.jsonfile 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 toPOLICY_ID: the ID of the access policyACCESS_LEVEL_NAME: the name of the access level that you created.
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 callsORGANIZATION_ID: your Cloud de Confiance organization ID
To use Context-Aware Access without enforcing the access level and denying access, you can bind the access policy 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 policy 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 access policies, the violations are logged to Cloud Audit Logs.
Bind access policies in dry-run mode
gcloud
To bind access policies 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 access policies in dry-run mode, create the request.json file with
the following content:
{
"principal": {
"serviceAccountProjectNumber": "TARGET_PROJECT_NUMBER"
},
"dryRunAccessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
}
Replace the following:
TARGET_PROJECT_NUMBER: the project number of the target projectPOLICY_ID: the ID of the access policyACCESS_LEVEL_NAME: the name of the access level
Check Cloud Audit Logs
This section describes how you can check Cloud Audit Logs for dry-run mode access denials for your service account. To learn more about searching for dry-run mode entries in Cloud Audit Logs, see View dry-run mode logs.
Console
To view Cloud Audit Logs dry-run mode service account access denials by using the Cloud de Confiance console, do the following:
In the Cloud de Confiance console, go to the Logs Explorer page:
If you use the search bar to find this page, then select the result whose subheading is Logging.
In the Cloud de Confiance console, select your project or organization.
In the Log query field, enter the following query:
protoPayload.serviceName="contextawareaccess.googleapis.com" protoPayload.metadata.dryRunEvaluationResult:DENIED SEARCH("`SERVICE_ACCOUNT_NAME`")In the time range selector, choose from a predefined relative time, like Last 30 minutes, Last 1 hour, or Last 24 hours, or specify a custom range.
gcloud
To view Cloud Audit Logs dry-run mode service account access denials by using the gcloud CLI, do the following:
gcloud logging read \
'protoPayload.serviceName="contextawareaccess.googleapis.com" AND
protoPayload.metadata.dryRunEvaluationResult:DENIED AND
SEARCH("`SERVICE_ACCOUNT_NAME`")' \
--organization=ORGANIZATION_ID
Replace the following:
ORGANIZATION_ID: the ID of the organizationSERVICE_ACCOUNT_NAME: the name of the service account
The gcloud logging read command supports the --freshness flag to view
logging information over relative timeframes. For example, by adding
--freshness=3h to the command, you can view dry-run mode log entries over
the last 3 hours.
Troubleshooting
This section describes how to troubleshoot Context-Aware Access for service accounts.
General troubleshooting
Review Cloud Audit Logs.
Use the following log query and review log entries for more information.
protoPayload.serviceName="contextawareaccess.googleapis.com"
Review the access level resource name that Context-Aware Access reports when it logs enforcement events.
Make sure that the access level is an org-level resource.
Make sure that the access level in your access policies is based on attributes that are supported for service accounts.
Verify that the access policy is bound to the intended service account.
Make sure that your user identity isn't access restricted by an access policy. This can happen when a user identity is a member of a Google group that has a bound access policy. That policy might restrict user access, in turn preventing call flow to the service account.
Contact your security administrator.
Access denied
Access is denied because of the following:
You bound the access policy in enforcement mode rather than dry-run mode.
Instead of enforcement, you can use dry-run mode to let service accounts access resources and log enforcement events without actually denying access to resources. Additionally, you can follow general troubleshooting instructions.
The access level needs to be updated to include more sources. For example, an IP address is being used that wasn't included in the access level when it was created.
What's next
- Learn how to manage access bindings.