Prepare and test your skills
Prepare and test your skills
Securing and protecting service accounts means giving every workload its own identity with only the permissions its task needs. In Google Cloud, Identity and Access Management (IAM) (opens in a new tab) binds roles directly to that service account, and the account is attached to the resource running the code, such as a Cloud Build job, App Engine version, or Google Kubernetes Engine (GKE) pod. User-managed accounts use the form SERVICE_ACCOUNT_ID@PROJECT_ID.iam.gserviceaccount.com and are created for one purpose, while default service accounts (opens in a new tab) are auto-created, shared, and historically over-permissioned.
Default service accounts increase blast radius because many workloads inherit the same broad permissions. The Compute Engine default account (PROJECT_NUMBER-compute@developer.gserviceaccount.com) and the App Engine default account (PROJECT_ID@appspot.gserviceaccount.com) may automatically receive the Editor role (roles/editor) on the project, which allows reading and modifying almost all resources. Cloud Build carries the same risk when no account is specified, because it may select an account with access to Cloud Source Repositories and any Cloud Storage bucket in the project. Traffic flows from the workload to Google Cloud APIs under the attached service account identity, so compromise of one workload can affect data owned by all workloads sharing that default account.
Fine-grained IAM grants the minimal predefined role to a specific service account identity instead of granting broad Owner, Editor, or Viewer roles. The binding adds the service account as a member for one role, for example granting roles/cloudtranslate.user to only that identity, so only that identity can use the permission. Scope is reduced further by granting the role on a single bucket, Artifact Registry repository, or dataset, by adding IAM Conditions, and by choosing task-specific roles over primitive roles. A function-build account shows this pattern with only Logs Writer to send logs, Artifact Registry Writer to store images, and Storage Object Viewer scoped by condition to buckets starting with run-sources-*, gcf-v2-sources-*, and gcf-v2-uploads-*.
Least-privilege identities for App Engine, Cloud Build, and GKE replace a shared default identity with a per-workload identity that limits which APIs the workload can call. In App Engine, a per-version service account is the identity for one deployed version, while an app-level custom default is the fallback identity for all services without a per-version account. If neither custom identity is set, App Engine falls back to the auto-created App Engine default account.
| App Engine identity | Scope of identity | Choose when |
|---|---|---|
| Per-version service account | One service version only | The version needs permissions that differ from the app default |
| App-level custom default service account | All services without a per-version account | One least-privilege identity can cover the whole app |
| Auto-created App Engine default service account | All services in the app | Only for legacy use; replace to remove Editor-level sharing |
Removing the default creates dependencies that must be replaced explicitly. App Engine flexible environment instances depend on Logs Writer, Monitoring Metric Writer, and Storage Object Viewer, so those three roles must be granted to the replacement account when Editor is removed. For GKE, development clusters that use the Compute Engine default account with full API access overprovision permissions because every workload on the node shares the node identity, and node account and scope settings cannot be changed after cluster creation. Production GKE associates a Kubernetes account with a Google account through Workload Identity in order:
.spec.serviceAccountName in the Kubernetes Deployment so pods run under that Kubernetes identity.Organization policy guardrails prevent new broad grants and disable risky defaults so least privilege persists across projects and folders. Enforcing iam.automaticIamGrantsForDefaultServiceAccounts blocks the automatic Editor grant to default service accounts, and organizations created after May 3, 2024 enforce this constraint by default. Related Cloud Build constraints cloudbuild.useBuildServiceAccount and cloudbuild.useComputeServiceAccount set to Not Enforced prevent use of the legacy build account and the default Compute Engine account for builds. Downgrading an existing over-privileged account requires validation before revoking access: first simulate with Policy Simulator, then grant minimal roles, then revoke the broad role. This order preserves logging, monitoring, and storage access while shrinking the trust boundary to the single workload.
Exam tip: The automatic Editor grant to default service accounts is blocked by iam.automaticIamGrantsForDefaultServiceAccounts, enforced by default only for organizations created after May 3, 2024; older organizations must enforce it explicitly.
Identifying scenarios requiring service accounts means choosing a non-human identity whenever automation must run without a person signing in. Service accounts (opens in a new tab) provide that identity for API scripts, delivery pipelines, runtime application code, and component-to-component calls. Using a service account instead of a human credential removes dependence on an individual login, allows least-privilege scoping to one function, and lets operations stop automation by disabling its identity.
API-only identities are service accounts that hold API credentials but cannot sign in through the user interface. Best practice is to create one dedicated service account for each API script and grant only the permissions that script needs, so compromise of one script does not expose administrative functions. Stopping a script is done by disabling or deleting only that script's account without affecting other automation or human users.
Cloud Deploy execution identities are the service accounts that Cloud Deploy runs as to render manifests and deploy releases. The identity is configured in the target definition with executionConfigs.privatePool.serviceAccount or executionConfigs.defaultPool.serviceAccount. Any account set there must have the Cloud Deploy Runner role (roles/clouddeploy.jobRunner) plus runtime permissions such as Container Developer and Service Account User for GKE or Cloud Run Developer and Service Account User for Cloud Run. Using an execution account from a different project than the target requires explicit cross-project trust, where the Cloud Deploy service agent and Cloud Build service agent are authorized in sequence with iam.serviceAccounts.actAs and Service Account Token Creator.
Runtime service identities are service accounts attached to compute resources so code can call Google Cloud APIs without human credentials. A Compute Engine instance can have only one associated service account, and changing that account requires stopping and restarting the instance. A Cloud Run instance configures its identity with the serviceAccountName field, and command-line automation can switch from user credentials to service account credentials with key-file activation.
Requiring permission to attach service accounts (opens in a new tab) separates identity from arbitrary grouping. A network tag is an arbitrary attribute that any principal who can edit the instance can add or remove while the instance is running. A service account represents the instance identity and can only be used to start an instance by a principal who holds the Service Account User role on that account plus permission to create instances. Service accounts and network tags cannot be mixed in any firewall rule, so target service accounts cannot be combined with target network tags, and ingress rules with tag-based targets cannot use service-account sources.
Stable workload identity is the core reason to choose a service account over a user account for long-lived applications. User accounts have passwords, support browser sign-in, and follow joiner-mover-leaver processes where leaving suspends or deletes the account. Service accounts have no password, cannot be used for browser sign-in, belong to a project as a resource, and keep the same identity even when the people who built the workload change teams or leave. Traffic flows from the application to Google Cloud APIs with the service account as the principal, while the authorization decision flows from IAM allow policies on the target resources back to the service account.
Privilege escalation through service accounts happens when a lower-privileged user gains higher-privileged access by using a service account's identity:
Because running code on a VM with SSH access lets the user reach every resource the VM's attached account can reach, shell access, deployment rights, and impersonation rights must be treated as equivalent to the data access they unlock. Workload Identity Federation (opens in a new tab) and short-lived impersonation reduce this risk by avoiding long-lived keys, and authorization for an attached workload succeeds only when both the IAM role on the account and the access scope on the Compute Engine instance allow it.
Exam tip: A firewall rule cannot mix service accounts and network tags — a rule with target service accounts cannot use network-tag sources, and a rule with target network tags cannot use service-account sources.
Continue with this study guide: Identifying scenarios requiring service accounts.
Creating, disabling, and authorizing service accounts covers the full lifecycle of custom non-human identities, from provisioning to revocation. Service account impersonation and short-lived credentials (opens in a new tab) let one identity act as a service account by minting temporary tokens instead of distributing long-lived keys. A source principal with permission to impersonate calls the Service Account Credentials API to create a temporary access token, ID token, JWT, or blob, and the target account's existing IAM permissions then control what that credential can access.
Short-lived credentials are temporary credentials minted with an internal Google-owned key, and by default OAuth 2.0 access tokens expire after 1 hour. Credentials are often obtained automatically when a workload uses Application Default Credentials (ADC), when gcloud runs with --impersonate-service-account, when code runs on an attached account on Compute Engine or App Engine, or when an external identity is federated through Workload Identity Federation. The flow moves trust without copying a secret: first the source authenticates with its own credentials, then the source calls the Credentials API on the target account, then the API returns a short-lived token signed by the target's Google-owned key.
The Credentials API prohibits using a short-lived credential for an account to generate a new access token for that same account, and it prohibits using it to sign a blob or JWT for the IAM, Credentials, or OAuth 2.0 APIs. A prohibited attempt fails with FAILED_PRECONDITION, and recovery requires authenticating with different credentials such as end-user credentials. The one exception is self-signed JWTs, where a self-signed JWT for an account can be used to generate a new access token for that same account.
Service account keys are RSA key pairs associated with an account, and each account can have up to 10 user-managed keys. Google-owned keys are held in escrow by Google and never exposed, while user-managed keys expose the private key as a downloadable file that must be stored securely.
| Key type | Private key access | Rotation and use |
|---|---|---|
| Google-owned and managed key pair | Held in escrow by Google and never directly accessible | Rotated regularly; used by Credentials API, App Engine, and Compute Engine to mint short-lived credentials |
| User-managed key pair | Downloadable private key; holder can sign a JWT and exchange it for an access token | Customer-managed lifetime; creates leakage and privilege-escalation risk |
Keyless delegation avoids downloading a static key by authenticating first with an attached account or federated identity and then using impersonation or signing APIs. Domain-wide delegation without keys follows an ordered signing flow: first authenticate with an attached account or federation, then construct a JWT with the sub claim set to the delegated user, then call signJwt to sign with the Google-owned key, then exchange the signed JWT for an access token.
Provisioning a custom service account creates a dedicated identity for code, then authorizes that identity before any workload uses it. A service account acts as an identity when it is granted IAM roles on APIs and resources, and it acts as a manageable resource when users are granted IAM roles on the account itself. A role granted to an account controls what jobs running as that account can do, while a role granted on an account controls who can become or use that account.
Provisioning follows an ordered workflow where each step depends on the previous identity existing:
gcloud iam service-accounts create to create the identity in the project.roles/iam.serviceAccountUser on the account email to the user who will attach it.--service-account set to the account email, so API calls from that resource authenticate as the account.In production, do not grant Owner, Editor, or Viewer to the account. Because an allow policy attached to a resource also applies to descendants, project-level grants affect all accounts in the project, while account-level grants affect only that single account. For lifecycle enforcement, disable an unused account first (opens in a new tab) and delete it only after a waiting period confirms nothing breaks. Disabled accounts retain bindings and can be re-enabled, while deleted default accounts cannot be recreated with the same internal ID.
Exam tip: Granting a role to a service account controls what that account can access, while granting Service Account User with iam.serviceAccounts.actAs on a service account controls who can attach and use that account.
Continue with this study guide: Creating, disabling, and authorizing service accounts.
Securing, auditing, and mitigating service account keys means replacing long-lived credentials with preventative policy and short-lived authentication wherever possible. A user-managed key pair (opens in a new tab) is a powerful credential where Google stores only the public portion and anyone holding the private key can act as the account. Each service account can have up to 10 such keys, created either when the IAM API generates the pair or when you generate the pair and upload only the public key.
Organization Policy constraints are preventative guardrails that block key creation and upload across the hierarchy. The constraint constraints/iam.disableServiceAccountKeyCreation prevents creating user-managed keys, while constraints/iam.disableServiceAccountKeyUpload prevents uploading a public key. Because policy is inherited, enforcement at the organization or folder level protects all child projects unless explicitly overridden. If an organization was created on or after May 3, 2024, both constraints are enforced by default as secure-by-default resources.
The key-expiry guardrail limits how long newly created keys remain valid when temporary key use cannot yet be eliminated. By default a new key never expires, but constraints/iam.serviceAccountKeyExpiryHours sets an expiry in hours that applies only to newly created keys. Best practice uses short expiries for temporary access, such as 8 hours for short testing, 24 hours for day-long access, and 168 hours for week-long access. Avoid expiry for production workloads where expiration could cause an outage, and do not set expiry unless key-creation blocking has already been in place and users confirm no permanent keys are required.
Keyless authentication lets external and on-Google workloads obtain short-lived credentials without a key file. Workload Identity Federation exchanges an external proof for a short-lived Google access token, often combined with service account impersonation to act as a specific account. The client library flow depends on a generated credential configuration file whose path is stored in GOOGLE_APPLICATION_CREDENTIALS, and Application Default Credentials then selects the correct external-account client type. Service account impersonation generates short-lived credentials without holding a private key when the caller holds iam.serviceAccounts.getAccessToken through the Service Account Token Creator role.
Short-lived lifetimes create tradeoffs between security and token-exchange cost. A 10-minute lifetime forces the library to repeat the full exchange every 10 minutes even if the third-party token is still valid. A lifetime greater than one hour requires adding the account as an allowed value under constraints/iam.allowServiceAccountCredentialLifetimeExtension. On Google Cloud, code on a compute resource should instead use the credentials of the attached service account, which avoids keys entirely.
Auditing joins three signals — what keys exist, whether keys are still used, and who used a key for what. Cloud Asset Inventory provides the organization-wide list of keys, Cloud Monitoring and Policy Intelligence provide usage and privilege signals, and Cloud Audit Logs provides the attributable activity record.
| Audit signal | Source system | Audit question answered |
|---|---|---|
| Key inventory | Cloud Asset Inventory export to BigQuery | Which persistent keys exist and in which projects and accounts |
| Usage and privilege | Policy Intelligence insights, Key Authentication Events metric, role recommendations | Which keys are inactive and which are high-risk due to excess permissions |
| Activity and attribution | Cloud Audit Logs with principalEmail and serviceAccountKeyName | Which identity and key performed an action and from where |
A deployable pipeline queries Cloud Asset Inventory daily, joins inventory with usage and permission data, and writes to a date-partitioned BigQuery table named sa_key_usage. Service account insights identify accounts that have not authenticated in 90 days, while the Key Authentication Events metric shows when an individual key was last used. Attribution only works with isolation: a dedicated account per application keeps principalEmail from blending applications, and a dedicated key per machine keeps serviceAccountKeyName from blending hosts. Security Command Center with Event Threat Detection tracks unauthorized creation, leaked-key use, new geography or user agent, anonymizing-proxy access, and anomalous impersonation.
Rotation designed for non-disruptive replacement creates the successor before removing its predecessor:
Automated rotation with Secret Manager and delivery pipelines replaces manual handling with scheduled renewal and workload-identity authentication. On GKE, the Secret Manager provider supports auto-rotation with a minimum interval of 120s, and pods authenticate to the Secret Manager API through workload identity without a key file. Compromise response first stops the credential, then removes authorization (opens in a new tab): disable the key to block authentication without permanently removing it, use Policy Analyzer to find every IAM grant held by the identity, rotate every exposed credential, and limit stolen-token use with VPC Service Controls perimeters, session-length limits, and access-level conditions.
Exam tip: Create, deploy, and verify the new service account key before deleting the old key — deleting first causes an outage, while verifying first preserves authentication during rotation.
Managing and creating short-lived credentials means issuing temporary tokens for a privilege-bearing service account without distributing long-lived keys. The request through the IAM Service Account Credentials API (opens in a new tab) always involves two identities: a caller that requests the credential and the privilege-bearing account (PRIV_SA) for which it is created. The caller must hold an impersonation role on PRIV_SA, and the resulting credential expires without a refresh token, so the caller must repeat the request after expiry.
An OAuth 2.0 access token is an opaque bearer token that authenticates a service account principal and authorizes calls to most Google APIs. The token flows from the caller to the Credentials API for issuance and then from the caller to the target Google API for use. The token is restricted to specific OAuth scopes such as https://www.googleapis.com/auth/cloud-platform, can be inspected at https://oauth2.googleapis.com/tokeninfo, cannot be revoked, and remains valid until expiry. Access tokens are created with serviceAccounts.generateAccessToken, or locally with gcloud auth print-access-token --impersonate-service-account=PRIV_SA. The caller needs the Service Account Token Creator role on PRIV_SA.
Service account access tokens live 5 minutes to 12 hours. The default maximum is 1 hour (3,600 seconds), extendable to 12 hours (43,200 seconds) only when the account is added to an organization policy that includes constraints/iam.allowServiceAccountCredentialLifetimeExtension. Choose access tokens when the workload needs to call Google Cloud APIs with the account's permissions for a bounded period.
An OpenID Connect (OIDC) ID token is a JWT that proves the identity of a service account to a specific receiving service, rather than authorizing broad API access. The token carries an aud audience claim that names the target URI, such as a Cloud Run service, Cloud Run function, or App Engine app, and the target validates that the audience matches itself. Traffic flows from the caller to the Credentials API for issuance, then from the caller to the target service for authentication (opens in a new tab). ID tokens are created with serviceAccounts:generateIdToken, which takes an audience and optional includeEmail flag. The caller must have iam.serviceAccounts.getOpenIdToken through the Service Account OpenID Connect Identity Token Creator role on PRIV_SA.
Some connecting services can automatically include the correct ID token when they invoke another service: Cloud Scheduler when it invokes an HTTP target, Cloud Tasks when it calls a service from an HTTP task, Pub/Sub with a message delivered to a push subscription, and Workflows when a step invokes another service. To generate an ID token by impersonation, follow an ordered separation:
A self-signed JWT is a client-issued credential that authenticates a service account without a network call to Google's authorization server. The client signs the JWT itself with key material and presents it directly as a bearer token, constrained to a scope or to a specific API that accepts this format, such as the Cloud Healthcare API. Its lifetime is 5 minutes to 1 hour, shorter than the maximum for IAM-issued access tokens. Choose it when the target API documents JWT bearer support and avoiding an extra exchange matters.
A signed Cloud Storage URL is a time-limited URL that grants temporary access to a specific resource without requiring the requester to hold IAM permissions. Possession of the URL is sufficient until it expires, so choose it when external users need bounded download or upload access without becoming IAM principals. Credential Access Boundaries are a different downscoping mechanism: they exchange a broad OAuth 2.0 access token at the Security Token Service for a new token restricted to specific Storage objects. The boundary can subtract permissions but cannot add permissions the principal does not already have, and downscoping is supported only for Cloud Storage and only for OAuth 2.0 access tokens.
| Credential | Issuer | Lifetime | Choose when |
|---|---|---|---|
| OAuth 2.0 access token | Google or IAM authorization server | 5 minutes to 12 hours, default max 1 hour | The workload calls most Google APIs with scopes as the account |
| OIDC ID token | Credentials API, metadata server, or gcloud | Short-lived, bound to audience | The workload authenticates to a specific service URL such as Cloud Run |
| Self-signed JWT | Client | 5 minutes to 1 hour | The target API documents JWT bearer support and direct presentation avoids a call |
| Signed Storage URL | Service account signing Storage URL | Time-limited per URL | An external party needs temporary object access without IAM grants |
Exam tip: Use an OAuth 2.0 access token to call Google APIs with scopes, and use an OIDC ID token to authenticate to a specific service URL with an audience claim.
Continue with this study guide: Managing and creating short-lived credentials.
Configuring Workload Identity Federation means letting workloads outside Google Cloud authenticate without downloadable keys. Workload Identity Federation (opens in a new tab) is the trust broker: the external identity provider authenticates the workload, Google Cloud validates that external credential, and the workload receives short-lived credentials to temporarily impersonate a service account. The service account then becomes the Google Cloud identity used for authorization.
External provider capabilities determine which workloads can federate and which protocol Google Cloud will use. Federation supports OpenID Connect (OIDC)-compatible and SAML 2.0-compatible providers, covering Active Directory, Microsoft Entra ID, ForgeRock, Okta, Ping Identity, other LDAP directories, and platforms such as AWS, Azure, GitHub, and GitLab. Architecting trust starts by confirming the external system can issue OIDC or SAML credentials that Google Cloud can validate.
The trust flow operates in order:
For applications outside Google Cloud, a credential configuration file binds this flow together by telling client libraries where to obtain the external credential and which account to impersonate, so no private RSA key is stored with the application.
Attribute mapping on a pool provider translates fields from the external token, referenced as assertion, into Google attributes such as google.subject, google.groups, and custom attributes. The mapping for google.subject defines the federated subject, for example google.subject=assertion.sub. Secure mappings rely only on attributes that are stable, authoritative, and unique over time. Mapping a reusable username or email can let a new user inherit an old binding, while a strong subject mapping is one-to-one in both directions. Changing a mapping after access is granted can change which external users match an existing binding, so mappings must be treated as a security boundary.
IAM policies grant roles to principal identifiers built from those mapped values. All identifiers use the numeric project number of the pool's project, the pool ID, and the expected mapped value.
| Selector | IAM member format | Choose when |
|---|---|---|
| By subject | principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT | Access is for one specific federated identity defined by google.subject |
| By group | principalSet://iam.googleapis.com/.../workloadIdentityPools/POOL_ID/group/GROUP | Access is for all members sharing a google.groups value |
| By attribute | principalSet://iam.googleapis.com/.../workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE | Access is for all identities sharing a custom mapped attribute |
A single-subject grant uses principal://, while group and custom-attribute grants address a set with principalSet://.
Federated workloads gain access either by direct IAM grants on the federated principal or by impersonating a dedicated service account with roles/iam.workloadIdentityUser. With direct access, the federated identifier is granted a resource role such as Storage Object Viewer. With impersonation, the service account is granted resource access and the federated identifier is granted Workload Identity User on that account. Best practice is to use a dedicated account per workload, keep it in the same project as the resources, and avoid granting Workload Identity User to all pool members.
| Access pattern | Identity used on resources | Choose when |
|---|---|---|
| Direct resource access | Federated workload identity | The workload has its own distinct identity and permissions can be granted directly |
| IAM service account impersonation | Target Google service account via ImpersonatedCredentials | Existing apps already use an account, or multiple identities must share one audited identity |
For GKE, direct resource access grants IAM roles directly to the Kubernetes service account identity, while impersonation binds the Kubernetes ServiceAccount to an IAM account that fronts the calls. Most Google Cloud APIs support direct access, but certain methods have federation limitations.
The Security Token Service exchange posts the provider-issued subject token to https://sts.googleapis.com/v1/token with grant_type, requested_token_type, an audience naming the pool and provider, subject_token_type, the subject_token, and a scope such as cloud-platform. A successful exchange returns a Bearer token commonly lasting 3600 seconds. Credential configuration files hold only non-sensitive metadata such as type: external_account, audience, token_url, and credential_source, so compromise of the file alone does not grant persistent access. The gcloud CLI (opens in a new tab) transparently posts credentials from gcloud auth login --cred-file=config.json to STS and refreshes the Google token only while the provider credential is still valid.
Controls limit what a stolen token can do by binding it to a narrow audience, a short lifetime, and explicit impersonation rights. Modifying a provider mapping requires iam.googleapis.com/workloadIdentityPoolProviders.update, so that permission must be limited to few administrators. Auditability depends on enabling data access logs for the Security Token Service API and IAM API in every project with pools or federation accounts, so both the exchange and short-lived credential creation are recorded. Application Default Credentials resolve in fixed order from GOOGLE_APPLICATION_CREDENTIALS to gcloud ADC login, App Engine, Cloud Shell, and Compute Engine credentials.
Exam tip: IAM members for Workload Identity Federation must use the numeric project number, not the project ID, in the principal:// and principalSet:// identifiers.
Continue with this study guide: Configuring Workload Identity Federation.
Managing service account impersonation means controlling how one authenticated principal temporarily acts as a more-privileged service account. Service account impersonation (opens in a new tab) occurs when a user or another service account authenticates as a service account to gain that account's permissions. When impersonation succeeds, data and API requests flow from the impersonator through short-lived credentials to the target resources under the service account's identity.
A service account is effectively as valuable as the resources it can reach, so impersonation paths must be audited. Privilege escalation typically falls into three peer categories: authenticating as the account by obtaining impersonation or key-creation permission, using a resource with an attached privileged account such as a VM or CI/CD pipeline to run code with its permissions, and modifying allow policies, groups, or custom roles to grant oneself ability to authenticate as the account. Permissions that enable these paths include iam.serviceAccounts.getAccessToken, getOpenIdToken, actAs, implicitDelegation, signBlob, signJwt, iam.serviceAccountKeys.create, deploymentmanager.deployments.create, and cloudbuild.builds.create.
Cloud Audit Logs links an impersonated operation back to its originating principal through service account delegation info. When a group member generates a short-lived token and calls an API as the account, the resource operation and token-generation event together show both the account identity and the user who requested it. Most services log both identities, while App Engine and GKE do not log the creator identity. Enabling Data Access audit logs for services such as compute.googleapis.com with ADMIN_READ, DATA_READ, and DATA_WRITE ensures privileged use is recorded, and exporting logs preserves history beyond default retention.
Binding impersonation roles on the target account means granting the role in the allow policy of the service account itself, not on the project, folder, or organization. The secure pattern uses gcloud iam service-accounts add-iam-policy-binding with the account email as the resource and Service Account Token Creator as the role. Because the grant applies to only that one account, the principal can impersonate only that identity. A project-wide grant has the opposite effect, because the member inherits token-creation ability for all accounts in that project, including highly privileged ones.
A complete delegation flow follows this order:
The documented elevated-access pattern grants the account roles/compute.admin on the project while the delegate group gets Token Creator only on that one account, plus Service Usage Consumer on the project so members can call iamcredentials.googleapis.com.
Short-lived credential roles and attachment roles control different paths to using an account's permissions. Credential roles let a principal mint tokens and impersonate directly, while the attachment role lets a principal attach the account to compute and then run code as that identity.
| Role | What it allows | Choose when |
|---|---|---|
| Service Account Token Creator | Create short-lived access tokens, ID tokens, signed JWTs, and signed blobs; use --impersonate-service-account | The principal must impersonate for API calls, development, or federation without keys |
| Service Account OpenID Connect Identity Token Creator | Create short-lived OIDC ID tokens only | The workload needs only identity proof with a custom audience |
| Service Account User | Attach the account to Compute Engine, App Engine, or Cloud Run via actAs | The user must deploy compute that runs as the account rather than calling APIs directly |
Least privilege narrows both who can impersonate and what the impersonated identity can do: avoid letting users impersonate accounts more privileged than themselves except for deliberate sudo-like elevation, avoid project-level impersonation grants, block key creation and upload, avoid letting users change allow policies of more-privileged accounts, limit shell and metadata-server access on VMs with privileged attached accounts, and never grant Owner, Editor, or Viewer to the production account.
Temporary elevation centralizes privilege in an account and distributes only short-lived use through group membership. An administrator creates a group such as elevated-compute-access, creates a scoped account, grants the group Token Creator on that account, and approves expiring membership per Cloud Identity guidance. Related options include temporary elevated access with justifications (opens in a new tab), IAM Conditions for expiring bindings, and Privileged Access Manager for just-in-time elevation. The supervisor pattern extends this by splitting ownership so a broker holds supervisor credentials and issues short-lived or downscoped tokens to downstream parts on demand, with connecting services such as Scheduler, Tasks, Pub/Sub push, and Workflows automatically attaching the correct ID token.
Containment for compromised tokens prioritizes blocking active tokens while preserving evidence. To block a compromised token, disable the account, apply an IAM deny policy for principal://iam.googleapis.com/projects/-/serviceAccounts/SA_EMAIL_ADDRESS, or delete the account. Deny policies block sensitive APIs for active tokens while investigation continues, whereas disabling or deleting immediately removes access from all workloads. Full response then revokes Token Creator from unauthorized principals, rotates compromised keys by creating and deploying a new key before disabling and deleting the old key, and waits before re-enabling so tokens expire.
Exam tip: Wait at least 60 minutes after disabling a service account before re-enabling it so compromised tokens expire; if an extended lifetime is configured, wait that specified time instead.
Continue with this study guide: Managing service account impersonation.
iam.automaticIamGrantsForDefaultServiceAccounts constraint blocks that automatic grant.iam.serviceAccounts.actAs only allows attaching that account to compute resources.Service Account Token Creator allows a principal to mint short-lived access tokens, ID tokens, signed JSON Web Tokens (JWTs), and signed blobs to directly impersonate a specific service account. Service Account User with iam.serviceAccounts.actAs only allows a principal to attach that account to Compute Engine, App Engine, or Cloud Run so code runs as that identity.
Use an OAuth 2.0 access token when the workload needs to call most Google APIs with the service account permissions for a bounded period, using OAuth scopes such as cloud-platform. Use an OpenID Connect (OIDC) ID token when the workload needs to authenticate to a specific service URL such as a Cloud Run service, Cloud Run function, or App Engine app, because the token carries an aud audience claim that names the target.
The default Compute Engine and App Engine service accounts are risky because they are shared across many workloads and may automatically receive the Editor role on the project, so compromise of one workload can affect data owned by all workloads sharing the account. Enforcing the iam.automaticIamGrantsForDefaultServiceAccounts organization policy constraint blocks that automatic Editor grant, and it is enforced by default only for organizations created after May 3, 2024, so older organizations must enforce it explicitly.
Create the new key, deploy it to every application that needs it, and verify the new key works in all dependent workloads before deleting the old key. Deleting first causes an outage, while verifying first preserves authentication during rotation, and each service account can have up to 10 user-managed keys to allow the successor and predecessor to coexist.
Last updated