Understanding service accounts

Background

A service account is a special type of Google account intended to represent a non-human user that needs to authenticate and be authorized to access data in Google APIs.

Typically, service accounts are used in scenarios such as:

  • Running workloads on virtual machines (VMs).
  • Running workloads on on-premises workstations or data centers that call Google APIs.
  • Running workloads which are not tied to the lifecycle of a human user.

Your application assumes the identity of the service account to call Google APIs, so that the users aren't directly involved.

Managing service accounts

Once you decide that you need a service account, you can ask yourself the following questions to understand how you're going to use the service account:

  • What resources can the service account access?
  • What permissions does the service account need?
  • Where will the code that assumes the identity of the service account be running—on Google Cloud or on-premises?

Use the following flowchart to figure out the responses to the above questions:

Service account flowchart

Note that service accounts can be thought of as both a resource and as an identity.

When thinking of the service account as an identity, you can grant a role to a service account, allowing it to access a resource (such as a project).

When thinking of a service account as a resource, you can grant roles to other users to access or manage that service account.

Granting access to service accounts

Granting access to a service account to access a resource is similar to granting access to any other identity. For example, if you have an application running on Compute Engine and you want the application to only have access to create objects in Cloud Storage. You can create a service account for the application and grant it the Storage Object Creator role. The following diagram illustrates this example:

Service account flowchart

Learn about Granting roles to all types of members, including service accounts.

Keeping track of service accounts

Over time, as you create more and more service accounts, you might lose track of which service account is used for what purpose.

The display name of a service account is a good way to capture additional information about the service account, such as the purpose of the service account or a contact person for the account. For new service accounts, you can populate the display name when creating the service account. For existing service accounts use the serviceAccounts.update() method to modify the display name.

Identifying unused service accounts

Unused service accounts create an unnecessary security risk, so we recommend disabling unused service accounts, then deleting the service accounts when you are sure that you no longer need them. You can use the following methods to identify unused service accounts:

Deleting and recreating service accounts

It is possible to delete a service account and then create a new service account with the same name.

When you delete a service account, its role bindings are not immediately deleted. Instead, the role bindings list the service account with the prefix deleted:. For an example, see Policies with deleted members.

If you create a new service account with the same name as a recently deleted service account, the old bindings may still exist; however, they will not apply to the new service account even though both accounts have the same email address. This behavior occurs because service accounts are given a unique ID within Identity and Access Management (IAM) at creation. Internally, all role bindings are granted using these IDs, not the service account's email address. Therefore, any role bindings that existed for a deleted service account do not apply to a new service account that uses the same email address.

Similarly, if you attach a service account to a resource, then delete the service account and create a new service account with the same name, the new service account will not be attached to the resource.

To prevent this unexpected behavior, consider using a new, unique name for every service account. Also, if you accidentally delete a service account, you can try to undelete the service account instead of creating a new service account.

If you cannot undelete the original service account, and you need to create a new service account with the same name and the same roles, you must grant the roles to the new service account. For details, see Policies with deleted members.

If you also need the new service account to be attached to the same resources as the original service account, do one of the following:

Permissions for service accounts

This section describes common scenarios for permissions granted to service accounts, or user accounts that have the permissions to impersonate service accounts:

Granting minimum permissions to service accounts

As with all types of members, you should only grant the service account the minimum set of permissions required to achieve its goal. Learn about granting roles to all types of members, including service accounts.

When granting permissions to users to access a service account, keep in mind that the user can access all the resources for which the service account has permissions. Therefore it's important to configure permissions of your service accounts carefully; that is, be strict about who on your team can act as (or impersonate) a service account. Use particular caution when allowing users to impersonate highly privileged service accounts, such as the Compute Engine and App Engine default service accounts.

Users with IAM roles to update the App Engine and Compute Engine instances (such as App Engine Deployer or Compute Instance Admin) can effectively run code as the service accounts used to run these instances, and indirectly gain access to all the resources for which the service accounts has access. Similarly, SSH access to a Compute Engine instance may also provide the ability to execute code as that instance.

Service account permissions for common scenarios

Service accounts can be used in many different scenarios, and each of them requires certain permissions. This section describes common scenarios and what permissions are required.

Attaching service accounts to resources

If you want to start a long-running job that authenticates as a service account, you need to attach a service account to the resource that will run the job.

Permissions:

  • Permissions to create the resource
  • iam.serviceAccounts.actAs

To find roles that include these permissions, search the roles list for the permissions.

There are several different Google Cloud resources that can run long-running jobs as service accounts. Some examples of these resources include:

  • Compute Engine VMs
  • App Engine apps
  • Cloud Functions

When you create these resources, you have the option to attach a service account. This service account acts as the resource's identity.

To create a resource and attach a service account, you need permissions to create that resource and permission to impersonate the service account that you will attach to the resource. Permission to impersonate the service account is provided by any role that includes the iam.serviceAccounts.actAs permission.

After you create the resource and attach a service account to it, you can start a long-running job on the resource. The job runs as the service account that is attached to the resource, and uses that service account to authorize requests to Google Cloud APIs.

To learn more about attaching service accounts to resources, see Attaching a service account to a resource.

Directly impersonating a service account

Permissions:

  • iam.serviceAccounts.getAccessToken
  • iam.serviceAccounts.signBlob
  • iam.serviceAccounts.signJwt
  • iam.serviceAccounts.implicitDelegation

Roles:

  • roles/iam.serviceAccountTokenCreator (Service Account Token Creator)

Once granted the required permissions, a user (or service) can directly impersonate (or assert) the identity of a service account in a few common scenarios.

First, the user may get short-term credentials for the service account using the iam.serviceAccounts.getAccessToken permission and by calling the generateAccessToken() method. By using short-term credentials, a user can issue commands to Google Cloud and can access all resources to which the service account has access. For example, this flow allows a user to use the gcloud --impersonate-service-account flag to impersonate the service account without requiring the use of a downloaded external service account key.

Second, the user may get artifacts signed by the Google-managed private key of the service account using the iam.serviceAccounts.signBlob permission and by calling either the signBlob() or signJwt() method. The Google-managed private key is always held in escrow and is never directly exposed. signBlob() allows signing of arbitrary payloads (such as Cloud Storage-signed URLs), while signJwt() only allows signing well-formed JWTs.

Finally, the user may impersonate (or assert) the service account without ever retrieving a credential for the service account. This is an advanced use case, and is only supported for programmatic access using the generateAccessToken() method. In scenarios with at least 3 service accounts, namely A, B, and C: service account A can get an access token for service account C if service account A is granted the iam.serviceAccounts.implicitDelegation permission on B, and B is granted the iam.serviceAccounts.getAccessToken permission on C.

Generating OpenID Connect (OIDC) ID tokens

Permissions:

  • iam.serviceAccounts.getOpenIdToken

Roles:

  • roles/iam.serviceAccountTokenCreator (Service Account Token Creator)

A user (or service) can generate an OpenID Connect (OIDC)-compatible JWT token signed by the Google OIDC Provider (accounts.google.com) that represents the identity of the service account using the iam.serviceAccounts.getOpenIdToken permission.

These tokens are not directly accepted by most Google APIs without your organization deploying additional identity federation to grant access to Google. There are a few exceptions—for example, Identity-Aware Proxy, which allows OIDC-based access to user-run applications.

Generating external private keys

Permissions:

  • iam.serviceAccountKeys.create

Roles:

  • roles/editor (Editor)
  • roles/iam.serviceAccountAdmin (Service Account Admin)

A user or service can generate external private key material (RSA) that can be used to authenticate directly to Google as the service account. This key material can then be used with Application Default Credentials (ADC) libraries, or with the gcloud auth activate-service-account command. Any person who gains access to the key material will then have full access to all resources to which the service account has access. Such private key material should be treated with the highest concern, and should be considered less secure the longer the material exists. Therefore, rotating private key material is critical to maintaining strong security.

Managing service account keys

There are two types of service account keys:

  • Google Cloud-managed keys. These keys are used by Google Cloud services such as App Engine and Compute Engine. They cannot be downloaded, and are automatically rotated and used for signing for a maximum of two weeks. The rotation process is probabilistic; usage of the new key will gradually ramp up and down over the key's lifetime. We recommend caching the public key set for a service account for at most 24 hours to ensure that you always have access to the current key set.

  • User-managed keys. These keys are created, downloadable, and managed by users. After you delete them from the service account, you cannot use them to authenticate.

For user-managed keys, you need to make sure that you have processes in place to address key management requirements such as:

  • Key storage
  • Key distribution
  • Key revocation
  • Key rotation
  • Protecting the keys from unauthorized users
  • Key recovery

Anyone who has access to a valid private key for a service account will be able to access resources through the service account. Note that the lifecycle of the key's access to the service account (and thus, the data the service account has access to) is independent of the lifecycle of the user who has downloaded the key.

Always discourage developers from checking keys into the source code or leaving them in the Downloads directory of their workstation.

To enhance the security of keys, follow the guidance below:

Using service accounts with Compute Engine

Compute Engine instances need to run as service accounts to have access to other Google Cloud resources. To make sure that your Compute Engine instances are more secure, consider the following:

  • You can create VMs in the same project with different service accounts. To change the service account of a VM after it's created, use the instances.setServiceAccount method.

  • You can grant IAM roles to service accounts to define what they can access. In many cases you won't need to rely on scopes anymore. This gives you the advantage of being able to modify permissions of a VM's service account without recreating the instance.

  • Since instances depend on their service accounts to have access to Google Cloud resources, avoid deleting service accounts when they are still used by running instances. If you delete the service accounts, the instances may start failing their operations.

Best practices

  • Specify who can act as service accounts. Users who are Service Account Users for a service account can indirectly access all the resources the service account has access to. Therefore, be cautious when granting the serviceAccountUser role to a user.

  • Grant the service account only the minimum set of permissions required to achieve their goal. Learn about granting roles to all types of members, including service accounts.

  • Create service accounts for each service with only the permissions required for that service.

  • Use the display name of a service account to keep track of the service accounts. When you create a service account, populate its display name with the purpose of the service account.

  • Define a naming convention for your service accounts.

  • Implement processes to automate the rotation of user-managed service account keys.

  • Take advantage of the IAM service account API to implement key rotation.

  • Audit service accounts and keys using either the serviceAccount.keys.list() method or the Logs Viewer page in the console.

  • Do not delete service accounts that are in use by running instances on App Engine or Compute Engine unless you want those applications to lose access to the service account.