Managing service account impersonation

This page describes how to allow members and resources to impersonate, or act as, an Identity and Access Management (IAM) service account. It also explains how to see which members are able to impersonate a given IAM service account.

Before you begin

Make sure you understand how service accounts work in IAM.

Allowing members to impersonate service accounts

There are several predefined roles that allow a member to impersonate a service account:

  • Service Account User (roles/iam.serviceAccountUser): Allows members to indirectly access all the resources that the service account can access. For example, if a member 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 member can impersonate the service account to create a Cloud SQL instance.

    This role also allows members to attach a service account to a resource, as explained on this page.

  • Service Account Token Creator (roles/iam.serviceAccountTokenCreator): Allows members to impersonate service accounts to create OAuth 2.0 access tokens, sign JSON Web Tokens (JWTs), and sign binary blobs so that they can be used for authentication. See Creating short-lived service account credentials for details.

  • Workload Identity User (roles/iam.workloadIdentityUser): Allows members to impersonate service accounts from GKE workloads. This role cannot be granted on individual service accounts, but can be granted on a project, folder, or organization.

Alternatively, you can grant a different predefined role, or a custom role, that includes the same permissions as these roles.

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:

Allowing a member to impersonate multiple service accounts

To allow a member to impersonate all service accounts created in a project, folder, or organization, grant a role on the project, folder, or organization:

Console

  1. In the Cloud Console, go to the IAM page.

    Go to the IAM page

  2. From the project selector at the top of the page, choose the project, folder, or organization on which you want to grant the role.

  3. Click Add.

  4. Enter your member's email address.

  5. Select a role that allows the member to impersonate service accounts. See the list of roles for impersonating service accounts.

  6. Click Save.

gcloud

To grant a member a role that allows them to impersonate a service account, modify the IAM policy for your project, folder, or organization.

  1. Read the IAM 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 policy on. This value should be one of the following: projects, resource-manager folders, or organizations.
    • resource-id: The ID of the resource that you want to set the policy on.

    The command stores the resource's policy in a policy.json file.

    If a 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 policy on the resource, the policy.json file only contains the default etag.

    When there is no existing policy, manually create the policy using the JSON in the following steps as a template.

  2. Modify the policy to grant the appropriate roles to your members. 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 member you want to grant it to.
    • If a binding already exists for the role, add the new member to the list of existing members. If your policy includes conditional role bindings, also ensure that the binding has the appropriate conditions before adding the member.

    If the bindings array doesn't already exist, you can create it.

    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:

    {
      "bindings": [
        {
          "role": "roles/iam.serviceAccountUser",
          "members": [
            "user:robin@example.com"
          ]
        },
        {
          "role": "roles/owner",
          "members": [
            "user:hollis@example.com"
          ]
        }
      ],
      "etag": "BwUqLaVeua8=",
      "version": 1
    }
    
  3. Write the updated 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 policy on. This value should be one of the following: projects, resource-manager folders, or organizations.
    • resource-id: The ID of the resource that you want to set the policy on.
    • policy-file: The path to the file that contains the updated policy.

    The command prints the updated policy with an updated etag value.

REST

To grant a role using the Resource Manager REST API, you need to read the current IAM policy for your project, folder, or organization; modify the policy to grant the desired roles; and then write the updated policy.

Read the IAM policy for the resource.

The Resource Manager API's getIamPolicy method gets a project, folder, or organization's IAM policy.

Before using any of the request data below, make the following replacements:

  • api-version: The API version to use. For projects and organizations, use v1. For folders, use v2.
  • resource-type: The resource type whose policy you want to manage. Use the value projects, folders, or organizations.
  • resource-id: Your Google Cloud project, organization, or folder 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://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:

You should receive a JSON response similar to the following:

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/owner",
      "members": [
        "user:owner@example.com"
      ]
    }
  ]
}

When there is no existing 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 policy to grant the appropriate roles to your members.

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 member you want to grant it to.
  • If a binding already exists for the role, add the new member to the list of existing members.

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 policy.

The Resource Manager API's setIamPolicy method sets the policy in the request as the new IAM policy for the project, folder, or organization.

Before using any of the request data below, make the following replacements:

  • api-version: The API version to use. For projects and organizations, use v1. For folders, use v2.
  • resource-type: The resource type whose policy you want to manage. Use the value projects, folders, or organizations.
  • resource-id: Your Google Cloud project, organization, or folder 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 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://iam.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 policy.

Allowing a member to impersonate a single service account

To allow a member to impersonate a single service account, grant a role on the service account:

Console

  1. In the Cloud Console, go to the Service Accounts page.

    Go to the Service Accounts page

  2. Select a project.

  3. Click the email address of the service account that you want to allow the member to impersonate.

  4. Click the Permissions tab.

  5. Under Members with access to this service account, click Grant Access.

  6. Enter your member's email address.

  7. Select a role that gives the member permission to impersonate service accounts. See the list of roles for impersonating service accounts.

  8. Click Save to apply the role to the project member.

To grant roles on multiple service accounts, repeat these steps for each service account.

gcloud

To grant a member a role that allows them to impersonate a service account, modify the IAM policy for your service account.

  1. Use the service-accounts get-iam-policy command to read the current 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 policy in a policy.json file.

    If a 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 policy set on the service account, the policy.json file only contains the default etag.

    When there is no existing policy, manually create the policy using the JSON in the following steps as a template.

  2. In a text editor, modify the bindings array in the policy.json file to grant the appropriate roles to your members. 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 member you want to grant it to.
    • If a binding already exists for the role, add the new member to the list of existing members. If your policy includes conditional role bindings, also ensure that the binding has the appropriate conditions before adding the member.

    If the bindings array doesn't already exist, you can create it.

    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:

    {
      "bindings": [
        {
          "role": "roles/iam.serviceAccountUser",
          "members": [
            "user:robin@example.com"
          ]
        },
        {
          "role": "roles/iam.serviceAccountAdmin",
          "members": [
            "user:hollis@example.com"
          ]
        }
      ],
      "etag": "BwUqLaVeua8=",
      "version": 1
    }
    
  3. Use the service-accounts set-iam-policy command to write the updated 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 policy.

    The command prints the updated 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 IAM policy, modify it to grant the desired roles, and then write the updated policy.

Read the service account's IAM policy.

The serviceAccounts.getIamPolicy method gets a service account's IAM policy.

Before using any of the request data below, make the following replacements:

  • project-id: Your Google Cloud project ID.
  • 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-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:

You should receive a JSON response similar to the following:

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:admin@example.com"
      ]
    }
  ]
}

When there is no existing 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 policy to grant the appropriate roles to your members.

In a text editor, modify the bindings array from the response body to grant the appropriate roles to your members. 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 member you want to grant it to.
  • If a binding already exists for the role, add the new member to the list of existing members.

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 policy.

The serviceAccounts.setIamPolicy method sets an updated IAM policy for the service account.

Before using any of the request data below, make the following replacements:

  • project-id: Your Google Cloud project ID.
  • 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: 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 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 policy.

Listing members that can access a service account

Use the Cloud Console to view all members 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:

  1. In the Cloud Console, go to the Service Accounts page.

    Go to Service accounts

  2. Select a project.

  3. Click the email address of the service account that you want to allow the member to impersonate.

  4. Click the Permissions tab. The Members with access to this service account section lists the members 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 member.

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:

  1. In the project where the service account is located, follow the steps on this page to enable service account impersonation across projects.
  2. Identify the project where you will create the resource.
  3. 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.

  4. Find the email address of the Google-managed service account for the service.

    Different services use different Google-managed service accounts. For details, see Google-managed service accounts and Service agents.

  5. Grant the Service Account Token Creator role (roles/iam.serviceAccountTokenCreator) to the Google-managed service accounts:

    Console

    1. In the Cloud Console, go to the Service accounts page.

      Go to Service accounts

    2. Select the project that owns the service account that you will attach to a resource.

    3. Find the service account that you will attach to a resource, and select its checkbox.

    4. In the Permissions pane, click Add member.

    5. In the New members field, enter the email address of the Google-managed service account.

    6. In the Select a role drop-down list, type Service Account Token Creator, then click the role.

    7. Click Save to save your changes.

    8. Optional: If you need to grant the role to another Google-managed service account, repeat the previous steps.

    gcloud

    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:google-sa-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.
    • google-sa-email: The email address for the Google-managed service account.

    The command prints the updated IAM policy for the user-managed service account.

    Optional: If you need to grant the role to another Google-managed service account, run the command again.

    REST

    To grant this role, use the read-modify-write pattern to update the IAM policy for your user-managed service account.

    First, read the IAM policy for the user-managed service account:

    The projects.serviceAccounts.getIamPolicy method returns the IAM policy for the service account.

    Before using any of the request data below, make the following replacements:

    • project-id: Your Google Cloud project ID.
    • 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 policy to grant the Service Account Token Creator role to the Google-managed service account. Replace google-sa-email with the email address for the Google-managed service account:

    {
      "version": 1,
      "etag": "BwWl3KCTUMY=",
      "bindings": [
        {
          "role": "roles/iam.serviceAccountTokenCreator",
          "members": [
            "serviceAccount:google-sa-email"
          ]
        },
        {
          "role": "roles/iam.serviceAccountUser",
          "members": [
            "serviceAccount:my-service-account@my-project.iam.gserviceaccount.com"
          ]
        }
      ]
    }
    

    Finally, write the updated policy:

    The projects.serviceAccounts.setIamPolicy method updates the IAM policy for your service account.

    Before using any of the request data below, make the following replacements:

    • project-id: Your Google Cloud project ID.
    • user-sa-name: The name of the user-managed service account that you are binding to a resource.
    • google-sa-email: The email address of the Google-managed service account 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:google-sa-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:google-sa-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 Notebooks Notebook instances
AI Platform Prediction Model versions
AI Platform Training Jobs
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
Pub/Sub Subscriptions

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 member.

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 member that created the short-lived credentials, as well as the service account that the member 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.

  • Recommended: Ensure that the iam.restrictCrossProjectServiceAccountLienRemoval boolean constraint is enforced for the project.

    This boolean constraint ensures that members can remove the project lien only if they have the resourcemanager.projects.updateLiens permission at the organization level. If this constraint is not enforced, members 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