This page describes how to allow principals and resources to impersonate, or act as, an Identity and Access Management (IAM) service account. It also explains how to see which principals are able to impersonate a given IAM service account.
Before you begin
Enable the IAM and Resource Manager APIs.
Make sure you understand how service accounts work in IAM.
Allowing principals to impersonate service accounts
There are several predefined roles that allow a principal to impersonate a service account:
Service Account User (
roles/iam.serviceAccountUser
): This role includes theiam.serviceAccounts.actAs
permission, which allows principals to indirectly access all the resources that the service account can access. For example, if a principal has the Service Account User role on a service account, and the service account has the Cloud SQL Admin role (roles/cloudsql.admin
) on the project, then the principal can impersonate the service account to create a Cloud SQL instance.This role also allows principals to attach a service account to a resource, as explained on this page.
This role does not allow principals to create short-lived credentials for service accounts, or to use the
--impersonate-service-account
flag for the Google Cloud CLI. To complete these tasks, you also need the Service Account Token Creator role.Service Account Token Creator (
roles/iam.serviceAccountTokenCreator
): This role lets principals impersonate service accounts to do the following:- Create OAuth 2.0 access tokens, which you can use to authenticate with Google APIs
- Create OpenID Connect (OIDC) ID tokens
- Sign JSON Web Tokens (JWTs) and binary blobs so that they can be used for authentication
See Creating short-lived service account credentials for details.
The role's permissions include the following:
iam.serviceAccounts.getAccessToken
: lets you create OAuth 2.0 access tokensiam.serviceAccounts.getOpenIdToken
: lets you create OpenID Connect (OICD) ID tokensiam.serviceAccounts.implicitDelegation
: lets service accounts get tokens in a delegation chainiam.serviceAccounts.signBlob
: lets you sign binary blobsiam.serviceAccounts.signJwt
: lets you sign JWTs
Workload Identity User (
roles/iam.workloadIdentityUser
): This role lets principals impersonate service accounts from GKE workloads.The role's permissions include the following:
iam.serviceAccounts.getAccessToken
: lets you create OAuth 2.0 access tokensiam.serviceAccounts.getOpenIdToken
: lets you create OpenID Connect (OICD) ID tokens
Alternatively, you can grant a different predefined role, or a custom role, that includes permissions to impersonate service accounts.
The following sections describe how to grant these roles on projects, folders, and organizations, and how to grant them on individual service accounts. Choose the level based on the amount of access that you want to grant:
- To allow a principal to impersonate all service accounts created in a project, folder, or organization, grant the role on the project, folder, or organization.
- To allow a principal to impersonate a single service account, grant the role on the service account.
Allowing a principal to impersonate multiple service accounts
To allow a principal to impersonate all service accounts created in a project, folder, or organization, grant a role on the project, folder, or organization:
Console
In the Google Cloud console, go to the IAM page.
From the project selector at the top of the page, choose the project, folder, or organization on which you want to grant the role.
Click Add.
Enter your principal's email address.
Select a role that allows the principal to impersonate service accounts. See the list of roles for impersonating service accounts.
Click Save.
gcloud CLI
To grant a principal a role that allows them to impersonate a service account, modify the allow policy for your project, folder, or organization.
Read the allow policy for the resource:
gcloud resource get-iam-policy resource-id \ --format=json > policy.json
Replace the following values:
-
resource
: The type of the resource that you want to set the allow policy on. This value should be one of the following:projects
,resource-manager folders
, ororganizations
. -
resource-id
: The ID of the resource that you want to set the allow policy on.
The command stores the resource's allow policy in a
policy.json
file.If an allow policy is already set on the resource, the
policy.json
file is similar to the following:{ "bindings": [ { "members": [ "user:hollis@example.com" ], "role": "roles/owner" } ], "etag": "BwUqLaVeua8=", "version": 1 }
If there is no allow policy on the resource, the
policy.json
file only contains the defaultetag
.When there is no existing allow policy, manually create the allow policy using the JSON in the following steps as a template.
-
Modify the allow policy to grant the appropriate roles to your principals. To grant a role, do one of the following:
- If a binding for the role does not exist, add an object to the
bindings
array that indicates the role you want to grant and the principal you want to grant it to. - If a binding already exists for the role, add the new principal to the list of existing principals. If your allow policy includes conditional role bindings, also ensure that the binding has the appropriate conditions before adding the principal.
If the
bindings
array doesn't already exist, you can create it.Example
To grant the Service Account User role (
roles/iam.serviceAccountUser
) torobin@example.com
, change the example shown in the previous step as follows:{ "bindings": [ { "role": "roles/iam.serviceAccountUser", "members": [ "user:robin@example.com" ] }, { "role": "roles/owner", "members": [ "user:hollis@example.com" ] } ], "etag": "BwUqLaVeua8=", "version": 1 }
- If a binding for the role does not exist, add an object to the
Write the updated allow policy:
gcloud resource set-iam-policy resource-id \ policy-file
Replace the following values:
-
resource
: The type of the resource that you want to set the allow policy on. This value should be one of the following:projects
,resource-manager folders
, ororganizations
. -
resource-id
: The ID of the resource that you want to set the allow policy on. policy-file
: The path to the file that contains the updated allow policy.
The command prints the updated allow policy with an updated
etag
value.-
REST
To grant a role using the Resource Manager REST API, you need to read the current allow policy for your project, folder, or organization; modify the allow policy to grant the desired roles; and then write the updated allow policy.
Read the allow policy for the resource.
The Resource Manager API's
getIamPolicy
method gets a project's, folder's, or organization's allow policy.
Before using any of the request data, make the following replacements:
API_VERSION
: The API version to use. For projects and organizations, usev1
. For folders, usev2
.RESOURCE_TYPE
: The resource type whose policy you want to manage. Use the valueprojects
,folders
, ororganizations
.RESOURCE_ID
: Your Google Cloud project, organization, or folder ID. Project IDs are alphanumeric strings, likemy-project
. Folder and organization IDs are numeric, like123456789012
.POLICY_VERSION
: The policy version to be returned. Requests should specify the most recent policy version, which is policy version 3. See Specifying a policy version when getting a policy for details.
HTTP method and URL:
POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:getIamPolicy
Request JSON body:
{ "options": { "requestedPolicyVersion": POLICY_VERSION } }
To send your request, expand one of these options:
The response contains the resource's allow policy. For example:
{ "version": 1, "etag": "BwWKmjvelug=", "bindings": [ { "role": "roles/owner", "members": [ "user:owner@example.com" ] } ] }
When there is no existing allow policy, the response contains only the default
etag
. If you get this response, add a version
field, set to
3, and a bindings
field, set to an empty array.
Modify the allow policy to grant the appropriate roles to your principals.
To grant a role, do one of the following:
- If a binding for the role does not exist, add an object to the
bindings
array that indicates the role you want to grant and the principal you want to grant it to. - If a binding already exists for the role, add the new principal to the list of existing principals.
Example:
To grant the Service Account User role (roles/iam.serviceAccountUser
) to
robin@example.com
, change the example shown in the previous step as
follows:
{ "version": 1, "etag": "BwUqLaVeua8=", "bindings": [ { "role": "roles/iam.serviceAccountUser", "members": [ "user:robin@example.com" ] }, { "role": "roles/owner", "members": [ "user:owner@example.com" ] } ] }
Write the updated allow policy.
The Resource Manager API's
setIamPolicy
method sets the policy in the request as the new allow policy for the project, folder, or organization.
Before using any of the request data, make the following replacements:
API_VERSION
: The API version to use. For projects and organizations, usev1
. For folders, usev2
.RESOURCE_TYPE
: The resource type whose policy you want to manage. Use the valueprojects
,folders
, ororganizations
.RESOURCE_ID
: Your Google Cloud project, organization, or folder ID. Project IDs are alphanumeric strings, likemy-project
. Folder and organization IDs are numeric, like123456789012
.-
POLICY
: A JSON representation of the policy that you want to set. For more information about the format of a policy, see the Policy reference.For example, to set the allow policy shown in the previous step, replace
POLICY
with the following:{ "version": 1, "etag": "BwUqLaVeua8=", "bindings": [ { "role": "roles/iam.serviceAccountUser", "members": [ "user:robin@example.com" ] }, { "role": "roles/owner", "members": [ "user:owner@example.com" ] } ] }
HTTP method and URL:
POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:setIamPolicy
Request JSON body:
{ "policy": POLICY }
To send your request, expand one of these options:
The response contains the updated allow policy.
Allowing a principal to impersonate a single service account
To allow a principal to impersonate a single service account, grant a role on the service account:
Console
In the Google Cloud console, go to the Service Accounts page.
Select a project.
Click the email address of the service account that you want to allow the principal to impersonate.
Click the Permissions tab.
Under Principals with access to this service account, click
Grant Access.Enter your principal's email address.
Select a role that gives the principal permission to impersonate service accounts. See the list of roles for impersonating service accounts.
Click Save to apply the role to the principal.
To grant roles on multiple service accounts, repeat these steps for each service account.
gcloud CLI
To grant a principal a role that allows them to impersonate a service account, modify the allow policy for your service account.
Use the
service-accounts get-iam-policy
command to read the current allow policy:gcloud iam service-accounts get-iam-policy sa-id \ --format=json > policy.json
Replace the following values:
sa-id
: The ID of your service account. This can either be the service account's email address in the form sa-name@project-id.iam.gserviceaccount.com, or the service account's unique numeric ID.
The command stores the service account's allow policy in a
policy.json
file.If an allow policy is already set on the service account, the
policy.json
file is similar to the following:{ "bindings": [ { "members": [ "user:hollis@example.com" ], "role": "roles/iam.serviceAccountAdmin" } ], "etag": "BwUqLaVeua8=", "version": 1 }
If there is no allow policy set on the service account, the
policy.json
file only contains the defaultetag
.When there is no existing allow policy, manually create the allow policy using the JSON in the following steps as a template.
In a text editor, modify the bindings array in the policy.json file to grant the appropriate roles to your principals. To grant a role, do one of the following:
- If a binding for the role does not exist, add a new object to the
bindings
array that defines the role you want to grant and the principal you want to grant it to. - If a binding already exists for the role, add the new principal to the list of existing principals. If your allow policy includes conditional role bindings, also ensure that the binding has the appropriate conditions before adding the principal.
If the
bindings
array doesn't already exist, you can create it.Example
To grant the Service Account User role (
roles/iam.serviceAccountUser
) torobin@example.com
, change the example shown in the previous step as follows:{ "bindings": [ { "role": "roles/iam.serviceAccountUser", "members": [ "user:robin@example.com" ] }, { "role": "roles/iam.serviceAccountAdmin", "members": [ "user:hollis@example.com" ] } ], "etag": "BwUqLaVeua8=", "version": 1 }
- If a binding for the role does not exist, add a new object to the
Use the
service-accounts set-iam-policy
command to write the updated allow policy:gcloud iam service-accounts set-iam-policy sa-id \ policy-file
Replace the following values:
sa-id
: The ID of your service account. This can either be the service account's email address in the form sa-name@project-id.iam.gserviceaccount.com, or the service account's unique numeric ID.policy-file
: The path to the file that contains the updated allow policy.
The command prints the updated allow policy with an updated
etag
value.
REST
To grant a role using the IAM REST API, you need to read the service account's current allow policy, modify it to grant the desired roles, and then write the updated allow policy.
Read the service account's allow policy.
The
serviceAccounts.getIamPolicy
method gets a service account's allow policy.
Before using any of the request data, make the following replacements:
PROJECT_ID
: Your Google Cloud project ID. Project IDs are alphanumeric strings, likemy-project
.SA_ID
: The ID of your service account. This can either be the service account's email address in the formSA_NAME@PROJECT_ID.iam.gserviceaccount.com
, or the service account's unique numeric ID.POLICY_VERSION
: The policy version to be returned. Requests should specify the most recent policy version, which is policy version 3. See Specifying a policy version when getting a policy for details.
HTTP method and URL:
POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_ID:getIamPolicy
Request JSON body:
{ "options": { "requestedPolicyVersion": POLICY_VERSION } }
To send your request, expand one of these options:
The response contains the service account's allow policy. For example:
{ "version": 1, "etag": "BwWKmjvelug=", "bindings": [ { "role": "roles/serviceAccountAdmin", "members": [ "user:admin@example.com" ] } ] }
When there is no existing allow policy, the response contains only the default
etag
. If you get this response, add a version
field, set to
3, and a bindings
field, set to an empty array.
Modify the allow policy to grant the appropriate roles to your principals.
In a text editor, modify the bindings array from the response body to grant the appropriate roles to your principals. To grant a role, do one of the following:
- If a binding for the role does not exist, add a new object to the
bindings
array that defines the role you want to grant and the principal you want to grant it to. - If a binding already exists for the role, add the new principal to the list of existing principals.
Example:
To grant the Service Account User role (roles/iam.serviceAccountUser
) to
robin@example.com
, change the example shown in the previous step as
follows:
{ "version": 1, "etag": "BwUqLaVeua8=", "bindings": [ { "role": "roles/iam.serviceAccountUser", "members": [ "user:robin@example.com" ] }, { "role": "roles/iam.serviceAccountAdmin", "members": [ "user:admin@example.com" ] } ] }
Write the updated allow policy.
The
serviceAccounts.setIamPolicy
method sets an updated allow policy for the service account.
Before using any of the request data, make the following replacements:
PROJECT_ID
: Your Google Cloud project ID. Project IDs are alphanumeric strings, likemy-project
.SA_ID
: The ID of your service account. This can either be the service account's email address in the formSA_NAME@PROJECT_ID.iam.gserviceaccount.com
, or the service account's unique numeric ID.-
POLICY
: A JSON representation of the policy that you want to set. For more information about the format of a policy, see the Policy reference.For example, to set the allow policy shown in the previous step, replace
policy
with the following:{ "version": 1, "etag": "BwUqLaVeua8=", "bindings": [ { "role": "roles/iam.serviceAccountUser", "members": [ "user:robin@example.com" ] }, { "role": "roles/serviceAccountAdmin", "members": [ "user:admin@example.com" ] } ] }
HTTP method and URL:
POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_ID:setIamPolicy
Request JSON body:
{ "policy": POLICY }
To send your request, expand one of these options:
The response contains the updated allow policy.
Listing principals that can access a service account
Use the Google Cloud console to view all principals that have access to a service account, either because of roles granted on the service account or because of roles granted on the project, folder, or organization:
In the Google Cloud console, go to the Service Accounts page.
Select a project.
Click the email address of the service account that you want to allow the principal to impersonate.
Click the Permissions tab. The Principals with access to this service account section lists the principals that can access the service account.
Attaching a service account to a resource
For some Google Cloud resources, you can specify a user-managed service account that the resource uses as its default identity. This process is known as attaching the service account to the resource, or associating the service account with the resource.
When a resource needs to access other Google Cloud services and resources, it impersonates the service account that is attached to itself. For example, if you attach a service account to a Compute Engine instance, and the applications on the instance use a client library to call Google Cloud APIs, those applications automatically impersonate the attached service account.
In most cases, you must attach a service account to a resource when you create that resource. After the resource is created, you cannot change which service account is attached to the resource. Compute Engine instances are an exception to this rule; you can change which service account is attached to an instance as needed.
Before you attach a service account to a resource, you must configure the service account. This process differs depending on whether the service account and the resource are in the same project or in different projects. After you configure the service account, you can create the resource and attach the service account to that resource.
Configuring for a resource in the same project
Before you attach a service account to another resource in the same project, grant roles to the service account so it can access the appropriate resources, just as you would grant roles to any other principal.
Configuring for a resource in a different project
In some cases, you might need to attach a service account to a resource that is located in a different project. For example, if you create all of your service accounts in a single project, you might need to attach one of them to a new resource in a different project.
Before you attach a service account to a resource in another project, do the following:
- In the project where the service account is located, follow the steps on this page to enable service account impersonation across projects.
- Identify the project where you will create the resource.
Identify the type of resource that you will attach the service account to, as well as the service that owns that type of resource.
For example, if you are creating a Pub/Sub subscription, then Pub/Sub is the service that owns the resource.
Find the email address of the service agent for the service.
Different services use different service agents. For details, see Service agents.
Grant the Service Account Token Creator role (
roles/iam.serviceAccountTokenCreator
) to the service agents:Console
In the Google Cloud console, go to the Service accounts page.
Select the project that owns the service account that you will attach to a resource.
Find the service account that you will attach to a resource, and select its checkbox.
In the Permissions pane, click Add principal.
In the New principals field, enter the email address of the service agent.
In the Select a role drop-down list, type
Service Account Token Creator
, then click the role.Click Save to save your changes.
Optional: If you need to grant the role to another service agent, repeat the previous steps.
gcloud CLI
Use the
gcloud iam service-accounts add-iam-policy-binding
command:gcloud iam service-accounts add-iam-policy-binding \ user-sa-name@project-id.iam.gserviceaccount.com \ --member=serviceAccount:service-agent-email \ --role=roles/iam.serviceAccountTokenCreator
Replace the following values:
user-sa-name
: The name of the user-managed service account that you are attaching to a resource.project-id
: The project ID where the user-managed service account is located.service-agent-email
: The email address for the service agent.
The command prints the updated allow policy for the user-managed service account.
Optional: If you need to grant the role to another service agent, run the command again.
REST
To grant this role, use the read-modify-write pattern to update the allow policy for your user-managed service account.
First, read the allow policy for the user-managed service account:
The
projects.serviceAccounts.getIamPolicy
method returns the allow policy for the service account.Before using any of the request data, make the following replacements:
PROJECT_ID
: Your Google Cloud project ID. Project IDs are alphanumeric strings, likemy-project
.-
USER_SA_NAME
: The name of the user-managed service account that you are binding to a resource.
HTTP method and URL:
POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/USER_SA_NAME@PROJECT_ID.iam.gserviceaccount.com:getIamPolicy
Request JSON body:
{ "requestedPolicyVersion": 3 }
To send your request, expand one of these options:
You should receive a JSON response similar to the following:
{ "version": 1, "etag": "BwWl3KCTUMY=", "bindings": [ { "role": "roles/iam.serviceAccountUser", "members": [ "serviceAccount:my-service-account@my-project.iam.gserviceaccount.com" ] } ] }
Next, modify the allow policy to grant the Service Account Token Creator role to the service agent. Replace
SERVICE_AGENT_EMAIL
with the email address for the service agent:{ "version": 1, "etag": "BwWl3KCTUMY=", "bindings": [ { "role": "roles/iam.serviceAccountTokenCreator", "members": [ "serviceAccount:SERVICE_AGENT_EMAIL" ] }, { "role": "roles/iam.serviceAccountUser", "members": [ "serviceAccount:my-service-account@my-project.iam.gserviceaccount.com" ] } ] }
Finally, write the updated allow policy:
The
projects.serviceAccounts.setIamPolicy
method updates the allow policy for your service account.Before using any of the request data, make the following replacements:
PROJECT_ID
: Your Google Cloud project ID. Project IDs are alphanumeric strings, likemy-project
.-
USER_SA_NAME
: The name of the user-managed service account that you are binding to a resource. -
SERVICE_AGENT_EMAIL
: The email address of the service agent that will create access tokens for your user-managed service account.
HTTP method and URL:
POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/USER_SA_NAME@PROJECT_ID.iam.gserviceaccount.com:setIamPolicy
Request JSON body:
{ "policy": { "version": 1, "etag": "BwWl3KCTUMY=", "bindings": [ { "role": "roles/iam.serviceAccountTokenCreator", "members": [ "serviceAccount:SERVICE_AGENT_EMAIL" ] }, { "role": "roles/iam.serviceAccountUser", "members": [ "serviceAccount:my-service-account@my-project.iam.gserviceaccount.com" ] } ] } }
To send your request, expand one of these options:
You should receive a JSON response similar to the following:
{ "version": 1, "etag": "BwWo331TkHE=", "bindings": [ { "role": "roles/iam.serviceAccountTokenCreator", "members": [ "serviceAccount:SERVICE_AGENT_EMAIL" ] }, { "role": "roles/iam.serviceAccountUser", "members": [ "serviceAccount:my-service-account@my-project.iam.gserviceaccount.com" ] } ] }
Attaching the service account to the new resource
After you configure the user-managed service account, you can create a new resource and attach the service account to that resource. Make sure you create the new resource in the appropriate project.
See the instructions for the type of resource that you want to create:
Attaching a service account when creating a resource | |
---|---|
AI Platform Prediction | Model versions |
AI Platform Training | Jobs |
App Engine standard environment | App versions |
App Engine flexible environment | App versions |
Cloud Composer | Environments |
Cloud Functions | Cloud Function |
Cloud Life Sciences | Pipelines |
Cloud Run | Services |
Cloud Scheduler | Jobs |
Cloud Source Repositories |
|
Compute Engine | |
Dataflow | Jobs |
Datalab | Instances |
Dataproc | Clusters |
Google Kubernetes Engine | |
Notebooks | Notebook instances |
Pub/Sub | Subscriptions |
Vertex AI | |
Workflows | Workflows |
After you have created the resource and attached the service account to that resource, you can grant roles to the service account so it can access the appropriate resources. This process is the same as granting a role to any other principal.
To learn how to grant roles, see Granting, changing, and revoking access to resources.
Interpreting audit logs
Cloud Audit Logs help you answer the questions "who did what, where, and when?" for your Google Cloud resources.
When you use short-lived credentials to impersonate a service account, most Google Cloud services create log entries that show the following identities:
- The service account that the short-lived credentials are impersonating
- The identity that created the short-lived credentials
You can use these log entries to identify the principal that created the short-lived credentials, as well as the service account that the principal impersonated.
For examples of audit log entries that show service account impersonation, see Impersonating a service account to access Google Cloud.
Enabling service account impersonation across projects
By default, you cannot create a service account in one project and attach it to a resource in another project. If you want to keep all of your service accounts in one project, you must update the organization policy for that project.
In the organization policy for the project where your service accounts are located, check the following boolean constraints:
Ensure that the
iam.disableCrossProjectServiceAccountUsage
boolean constraint is not enforced for the project.This boolean constraint controls whether you can attach a service account to a resource in another project. The constraint is enforced by default.
When this constraint is not enforced, IAM adds a project lien that prevents the project from being deleted. This lien has the origin
iam.googleapis.com/cross-project-service-accounts
. We strongly discourage you from deleting this lien.This constraint is available only at the project level, not at the folder or organization level.
Recommended: Ensure that the
iam.restrictCrossProjectServiceAccountLienRemoval
boolean constraint is enforced for the project.This boolean constraint ensures that principals can remove the project lien only if they have the
resourcemanager.projects.updateLiens
permission at the organization level. If this constraint is not enforced, principals can remove the project lien if they have this permission at the project level.
To learn how to view or change a boolean constraint in an organization policy, see Setting a boolean constraint.
Disabling service account impersonation across projects
If you previously enabled service account impersonation across projects, we strongly discourage you from disabling this feature, especially in production environments.
Specifically, in the project where your service accounts are located, you should not make any of these changes:
- Do not update the project's organization policy to enforce the
iam.disableCrossProjectServiceAccountUsage
boolean constraint. - Do not update the project's organization policy to not enforce the
iam.restrictCrossProjectServiceAccountLienRemoval
boolean constraint. - Do not remove the project lien with the origin
iam.googleapis.com/cross-project-service-accounts
, which prevents you from deleting the project. - Do not delete the project.
If you are willing to accept the risk of disabling this feature, you can reduce your risk by disabling the service accounts that you are using across projects, then monitoring your Google Cloud environment for issues. If you see any issues, you can re-enable the service accounts. If you do not see any issues, then you might not have any Google Cloud resources that depend on a service account in a different project.
What's next
- Find out how to attach a service account to a Compute Engine instance.
- Review and apply best practices for securing service accounts.
- Learn how to make a principal's access conditional with conditional role bindings.
- Learn more about audit logging for IAM.