Best practices for using and managing service accounts

Service accounts represent non-human users. They're intended for scenarios where a workload, such as a custom application, needs to access resources or perform actions without end-user involvement.

Service accounts differ from normal user accounts in multiple ways:

  • They don't have a password and can't be used for browser-based sign-in.
  • They're created and managed as a resource that belongs to a Google Cloud project. In contrast, users are managed in a Cloud Identity or Google Workspace account.
  • They're specific to Google Cloud. In contrast, the users managed in Cloud Identity or Google Workspace work across a multitude of Google products and services.

This guide presents best practices for managing, using, and securing service accounts.

Choosing when to use service accounts

Service accounts can be used for many different purposes, but they aren't always the best choice. The following section provides guidance about when to use service accounts, and when to avoid them.

Use service accounts for unattended scenarios

Not every application interacts with human users—instead, an application might be running in the background unattended. Unattended applications include batch jobs, worker processes that dispatch messages read from a queue, or a resource-monitoring agent.

Whenever an unattended application needs to access a resource, like a Cloud Storage bucket, it must act on its own behalf, not on behalf of any end user. To act on its own behalf, an application needs its own identity that's unrelated to any end-user identity.

To equip an application with its own identity, create a service account for the application, and grant the service account access to the resources that the application needs to access. By letting an application use its own service account, you help ensure that the application can work without user interaction. In addition, you also ensure that any resource accesses initiated by the application can be attributed back to the same application.

Use service accounts to perform a transition between principals

An application that interacts with end users can use Google Sign-In to authenticate those users, but it isn't obliged to do so: Instead, an application might rely on a third-party identity provider or might implement a custom authentication scheme to authenticate its users.

If an application uses third-party or custom identities and needs to access a resource, such as a BigQuery dataset or a Cloud Storage bucket, it must perform a transition between principals. Because Google Cloud APIs don't recognize third-party or custom identities, the application can't propagate the end-user's identity to BigQuery or Cloud Storage. Instead, the application has to perform the access by using a different Google identity.

To let an application perform a transition between principals, create a service account for the application and grant it access to the resources that the application needs to access. Whenever the application needs to access a Google Cloud resource, make sure that it has authenticated the end user first, then let it use the service account to access the resource.

Transitions between principals can limit the usefulness of Cloud Audit Logs of affected Google Cloud resources: Because the application uses a service account to access resources, Cloud Audit Logs might not contain a clear indication of whether or not an action was done on behalf of a particular end user. To help ensure non-repudiability, extend your application to write a custom log record whenever a transition between principals occurs. That way, you can trace back which end user triggered a resource access.

An application might require access to sensitive or personal user data. Examples of such data include a user's mailbox or calendar, documents stored on Drive, or a BigQuery dataset that contains sensitive data.

Using a service account to access user data can be appropriate if the application performs unattended background tasks, such as indexing or data loss prevention (DLP) scans, or if the end user hasn't authenticated with a Google identity. In all other scenarios where an application acts on an end user's behalf, it's best to avoid using service accounts.

Instead of using a service account to access user data (possibly performing a principal transition), use the OAuth consent flow to request the end user's consent. Then let the application act under the end user's identity. By using OAuth instead of a service account, you help ensure that:

  • Users can review which resources they're about to grant the application access to, and can explicitly express or deny their consent.
  • Users can revoke their consent on their My Account page at any time.
  • You don't need a service account that has unfettered access to all user's data.

By letting the application use end-user credentials, you defer permission checks to Google Cloud APIs. This approach limits the risk of accidentally exposing data that the user shouldn't be allowed to access because of a coding error (confused deputy problem).

Don't use service accounts during development

During your daily work, you might use tools such as the gcloud command-line tool, gsutil, or terraform. Don't use a service account to run these tools. Instead, let them use your credentials by running gcloud auth login (for the gcloud tool and gsutil) or gcloud auth application-default login (for terraform and other third-party tools) first.

You can use a similar approach for developing and debugging applications that you plan to deploy on Google Cloud. Once deployed, the application might require a service account—but if you run it on your local workstation, you can let it use your personal credentials.

To help ensure that your application supports both personal credentials and service account credentials, use the Cloud Client Libraries to find credentials automatically.

Using service accounts

The typical way for users to authenticate to Google Cloud is to sign in by using a username and password or to use single sign-on (SSO). Service accounts do not have a password and can't use SSO. Instead, service accounts support a different set of authentication methods. The following section provides best practices for selecting an authentication method.

How to use service accounts

Use attached service accounts when possible

To allow an application deployed on Google Cloud to use a service account, attach the service account to the underlying compute resource. By attaching the service account, you enable the application to obtain tokens for the service account and to use the tokens to access Google Cloud APIs and resources.

To obtain access tokens in the application, use the client libraries if possible. The client libraries automatically detect if the application is running on a compute resource with an attached service account.

In situations when using the client libraries isn't practical, adjust your application to programmatically obtain tokens from the metadata server. Compute resources that support access to the metadata server include:

For a full list of compute resources that let you attach a service account, see Managing service account impersonation.

Use Workload Identity to attach service accounts to Kubernetes pods

If you use Google Kubernetes Engine, then you might be running a combination of different applications on a single GKE cluster. The individual applications are likely to differ in which resources and APIs they need to access.

If you attach a service account to a GKE cluster or one of its node pools, then, by default, all pods running on the cluster or node pool can impersonate the service account. Sharing a single service account across different applications makes it difficult to assign the correct set of privileges to the service account:

  • If you only grant access to resources that all applications require, then some applications might fail to work because they lack access to certain resources.
  • If you grant access to all resources that any particular application needs, then you might be over-granting access.

A better approach to manage access to resources in a GKE environment is to use Workload Identity:

  1. Don't attach service accounts to GKE clusters or node pools.
  2. Create a dedicated service account for each Kubernetes pod that requires access to Google APIs or resources.
  3. Create a Kubernetes service account for each Kubernetes pod that requires access to Google APIs or resources and attach it to the pod.
  4. Use Workload Identity to create a mapping between the service accounts and their corresponding Kubernetes service accounts.

Use workload identity federation to let applications running on-premises or on other cloud providers use a service account

If your application runs on-premises or on another cloud provider, then you can't attach a service account to the underlying compute resources. However, the application might have access to environment-specific credentials such as:

  • AWS temporary credentials
  • Azure Active Directory access tokens
  • OpenID access tokens or ID tokens issued by an on-premises identity provider like Active Directory Federation Services (AD FS) or KeyCloak

If your application has access to one of these credentials and needs access to Google Cloud APIs or resources, use Workload Identity federation.

Workload identity federation lets you create a one-way trust relationship between a Google Cloud project and an external identity provider. Once you've established the trust, applications can use credentials issued by the trusted identity provider to impersonate a service account by following a three-step process:

  1. Obtain a credential from the trusted identity provider, for example an OpenID Connect ID token.
  2. Use the Security Token Service (STS) API to exchange the credential against a short-lived Google STS token.
  3. Use the STS token to authenticate to the IAM Service Account Credentials API and obtain short-lived Google access tokens for a service account.

By using workload identity federation, you can let applications use the authentication mechanisms that the external environment provides and you avoid having to store and manage service account keys.

Use the IAM Credentials API to broker credentials

Some applications only require access to certain resources at specific times or under specific circumstances. For example:

  • An application might require access to configuration data during startup, but might not require that access once it's initialized.
  • A supervisor application might periodically start background jobs where each job has different access requirements.

In such scenarios, using a single service account and granting it access to all resources goes against the principle of least privilege: At any point in time, the application is likely to have access to more resources than it actually needs.

To help ensure that the different parts of your application only have access to the resources they need, use the IAM Credentials API to broker short-lived credentials:

  • Create dedicated service accounts for each part of the application or use case and only grant the service account access to the necessary resources.
  • Create another service account that acts as the supervisor. Grant the supervisor service account the Service Account Token Creator role on the other service accounts so that it can request short-lived access tokens for these service accounts.
  • Split your application so that one part of the application serves as token broker and only let this part of the application use the supervisor service accounts.
  • Use the token broker to issue short-lived service accounts to the other parts of the application.

Use service account keys if there's no viable alternative

Occasionally, you might encounter a situation where attaching a service account isn't possible, and using Workload Identity or workload identity federation aren't viable options either. For example, one of your on-premises applications might need access to Google Cloud resources, but your on-premises identity provider isn't compatible with OpenID Connect and therefore can't be used for workload identity federation.

In situations where other authentication approaches aren't viable, create a service account key for the application. A service account key lets an application authenticate as a service account, similar to how a user might authenticate with a username and password. Service account keys are a type of secret and must be protected from unauthorized access. It's best to store them in a secure location, like a key vault, and to rotate them frequently.

Managing service accounts

Service accounts differ from normal user accounts, not only in how they're used, but also in how they must be managed. The following sections provide best practices for managing service accounts.

Manage service accounts as resources

Regular user accounts are typically managed according to an organization's joiner-mover-leaver processes: When an employee joins, a new user account is created for them. When they move departments, their user account is updated. And when they leave the company, their user account is suspended or deleted.

In contrast, service accounts aren't associated with any particular employee. Instead, it's best to think of service accounts as resources that belong to—or are part of—another resource, such as a particular VM instance or an application.

To effectively manage service accounts, don't look at service accounts in isolation. Instead, consider them in the context of the resource they're associated with and manage the service account and its associated resource as one unit: Apply the same processes, same lifecycle, and same diligence to the service account and its associated resource, and use the same tools to manage them.

Create single-purpose service accounts

Sharing a single service account across multiple applications can complicate the management of the service account:

  • The applications might have different life cycles. If an application is decommissioned, it might not be clear whether the service account can be decommissioned as well or whether it's still needed.
  • Over time, the access requirements of applications might diverge. If applications use the same service account, then you might need to grant the service account access to an increasing number of resources, which in turn increases the overall risk.
  • Cloud Audit Logs include the name of the service account that performed a change or accessed data, but they don't show the name of the application that used the service account. If multiple applications share a service account, you might not be able to trace activity back to the correct application.

To avoid these complications, create dedicated service accounts for each application and avoid using default service accounts.

Follow a naming and documentation convention

To help track the association between a service and an application or resource, follow a naming convention when creating new service accounts:

  • Add a prefix to the service account email address that identifies how the account is used. For example:
    • vm- for service accounts attached to a VM instance.
    • wi- for service accounts used by Workload Identity.
    • wif- for service accounts used by workload identity federation.
    • onprem- for service accounts used by on-premises applications.
  • Embed the name of the application in the service account email address, for example: vm-travelexpenses@ if the VM runs a travel expenses application.
  • Use the description field to add a contact person, links to relevant documentation, or other notes.

Don't embed sensitive information or terms in the email address of a service account.

Identify and disable unused service accounts

When a service account isn't used anymore, disable the service account. By disabling unused service accounts, you reduce the risk of the service accounts being abused for lateral movement or for privilege escalation by a bad actor.

For single-purpose service accounts that are associated with a particular resource, such as a VM instance, disable the service account as soon as the associated resource is disabled or deleted.

For service accounts that are used for multiple purposes or shared across multiple resources, it can be more difficult to identify whether the service account is still used. In these cases, use the following methods:

Disable unused service accounts before deleting them

If you delete a service account and then create a new service account with the same name, the new service account is assigned a different identity. As a result, none of the original IAM bindings apply to the new service account. In contrast, if you disable and re-enable a service account, all IAM bindings stay intact.

To avoid inadvertently losing IAM bindings, it's best to not delete service accounts immediately. Instead, disable a service account if it isn't needed anymore and only delete it after a certain period has elapsed.

Never delete default service accounts such as the App Engine or Compute Engine default service account. These service accounts can't be recreated without disabling and reenabling the respective API, which might break your existing deployment. If you don't use the default service accounts, disable them instead.

What's next