User Identity vs Service Account in GCP: Differences, Use Cases, and Best Practices

In GCP, every identity is either a user identity (a human) or a service account (a workload or application). User identities sign in interactively with a password. Service accounts authenticate automatically using short-lived tokens. The practical rule is straightforward: humans use user identities, automated code uses service accounts.

By the end of this page you will understand the difference between these two identity types, how to pick the right one for each situation, and how Application Default Credentials and Workload Identity Federation fit into the picture.

The simple explanation

Think of a user identity as an employee badge for a person and a service account as an access badge for a piece of software.

Here is the fundamental split:

  • User identity: a human who signs in through a browser with a password and MFA.
  • Service account: a workload or application that authenticates automatically using short-lived tokens, with no human present.
  • Humans should not use service accounts for their own access. Service accounts cannot use interactive login flows.
  • The default rule: if something runs automatically, give it a service account. If a person is doing it, they use their own identity.

User identity vs service account at a glance

User identityService account
RepresentsA humanAn application or workload
Used byEngineers, admins, developersApps, VMs, pipelines, automated jobs
Login styleInteractive (browser + password + MFA)Non-interactive (short-lived tokens)
Typical use caseCloud Console, running gcloud locallyCloud Run calling Storage, CI/CD deploying infrastructure
Tied to a personYesNo (belongs to a project)
Safe for automationNoYes
Best place to use itInteractive human sessionsAny workload that runs without a human present
Common riskUsed in automation, breaks when person leavesOver-permissioned, key file committed to git
Quick decision rule

If a human is clicking or typing, it is a user identity. If code is running without anyone present, it is a service account. That single distinction resolves almost every identity decision you will face in GCP.

How it works

User identities

A user identity is a Google Account (Gmail) or a Cloud Identity or Google Workspace account managed by your organisation. When you access the Cloud Console, run gcloud on your machine, or grant access to a colleague, you are working with user identities.

Authentication is interactive. You enter a password, complete MFA if required, and Google issues a short-lived OAuth token. The IAM roles bound to your account determine what you are allowed to do.

# Grant a user IAM access to a project
gcloud projects add-iam-policy-binding my-project \
  --member="user:alice@example.com" \
  --role="roles/viewer"

Service accounts

A service account is a special GCP identity for non-human workloads. It has an email-style identifier and is managed as a resource within a GCP project. It belongs to the project, not to any individual. When a VM, Cloud Run service, or GKE pod runs with an attached service account, GCP automatically issues short-lived credentials through the metadata server. Your code does not need to manage credentials at all.

IAM roles work the same way for service accounts as for users. You grant the service account the roles it needs, and GCP enforces those permissions on every API call.

# Create a service account
gcloud iam service-accounts create backend-api \
  --display-name="Backend API" \
  --project=my-project

# Grant it a narrowly scoped role
gcloud projects add-iam-policy-binding my-project \
  --member="serviceAccount:backend-api@my-project.iam.gserviceaccount.com" \
  --role="roles/storage.objectViewer"
Why user credentials do not belong in automation

User credentials are tied to an individual. When that person changes roles or leaves your organisation, their access is revoked and any automation using their credentials breaks. It is a reliability problem on top of a security problem. Service accounts belong to the project. Team changes do not affect them.

When to use a user identity

Use a user identity when a human is directly taking the action:

  • An engineer opens the Cloud Console to create a VM, inspect logs, or review IAM bindings
  • A developer runs gcloud commands on their local machine
  • An admin grants or revokes IAM access for a colleague
  • A team member reviews resources in the Console during an incident
  • You are granting access to a new contractor or team member

For local development, developers also authenticate as their user identity through Application Default Credentials so that local code can call GCP APIs. This is covered in the Application Default Credentials section below.

Do not share your credentials with an application

Never pass your personal credentials to a script, pipeline, or application. Credentials tied to your account give that automation your full permissions across GCP. When your access is eventually revoked, the automation breaks silently. Use a service account instead.

When to use a service account

Use a service account any time automated code needs to interact with GCP:

  • A Cloud Run service calling Cloud Storage. Attach a service account with roles/storage.objectViewer to the Cloud Run service. No key file. No environment variable. Application Default Credentials finds the attached account automatically.

  • A Compute Engine VM reading from Firestore. Attach a dedicated service account at VM creation time instead of accepting the broad default Compute Engine service account.

  • A CI/CD pipeline deploying infrastructure. A GitHub Actions workflow or Cloud Build job should run as a service account with only the deployment roles it needs. Use Workload Identity Federation to avoid creating a key file.

  • A GKE pod accessing a GCP API. Workload Identity binds a Kubernetes service account to a GCP service account so each pod has its own narrowly scoped identity.

  • A Cloud Function triggered by Pub/Sub. The function runs as a service account and can be granted only the permissions that specific function requires.

  • Any scheduled or automated job. Cloud Scheduler, Cloud Tasks, and Cloud Workflows all support running as a service account.

The clean rule

If a resource runs on GCP, attach a service account to it. The platform handles credentials through the metadata server automatically. No key file. No stored credential. No environment variable pointing to a JSON file. For a deeper guide to creating and managing service accounts, see GCP Service Accounts.

Common mistakes

  1. Using a personal account in automation. The script works today. Six months later, that person moves teams, their access is revoked, and the pipeline breaks at 2am. Service accounts are not tied to individuals. Use them for all automated tasks.

  2. Sharing one service account across multiple workloads. Revoking or adjusting access for one workload then affects all of them. A compromised application exposes every other application sharing that identity. Create one service account per distinct workload.

  3. Granting Editor or Owner to a service account. A service account reading from Cloud Storage needs roles/storage.objectViewer, not roles/editor. Broad roles mean a compromised service account causes broad damage. Follow the principle of least privilege.

  4. Committing a key file to git. A key.json file in a repository, even a private one, is a leaked credential. Automated scanners find them within minutes. Use attached service accounts for GCP workloads and Workload Identity Federation for external ones. If a key file is unavoidable, store it in Secret Manager, not in source control. See Why Service Account Keys Are Dangerous for the full picture.

  5. Confusing gcloud auth login with gcloud auth application-default login. These serve different purposes. The first authenticates the gcloud CLI. The second sets the credentials that GCP client libraries use in your application code. For local development, you typically need both.

User identity vs service account: key differences

The distinction between a user identity and a service account is not just semantic. It affects how authentication works, how credentials are managed, and what happens when people join or leave your organisation.

Ownership and lifecycle

Authentication mechanism

User identities use interactive authentication: a browser-based OAuth flow with a password and MFA. Service accounts use non-interactive authentication: short-lived access tokens issued by the metadata server (for attached accounts) or via an external token exchange through Workload Identity Federation. No password, no MFA prompt, no browser required.

What happens in IAM

Both types are principals in IAM. You bind IAM roles to them using the same add-iam-policy-binding command. The member prefix differs: user: for user identities, serviceAccount: for service accounts. Apart from that, IAM treats them identically.

Safe for automation

User identities are not safe for automation because they are tied to an individual and require interactive re-authentication when tokens expire. Service accounts are designed for automation: credentials refresh automatically, there is no interactive login requirement, and they can be granted the minimum permissions a workload needs.

Never mix these up

Putting user credentials in automation is both a reliability and a security risk. Service accounts cannot perform interactive browser logins. Keep the two identity types completely separate. If you hit permission errors after setting up an identity, see IAM Access Denied Errors for the most common causes.

Local development vs production

The identity your code uses changes depending on where it runs. Here is how each environment should be set up.

Local development

When a developer runs code on their own machine, they typically authenticate using their user identity through Application Default Credentials:

# Authenticate the gcloud CLI (for running gcloud commands)
gcloud auth login

# Set credentials for GCP client libraries in your application code
gcloud auth application-default login
Local code runs with your personal permissions

After gcloud auth application-default login, your local application code has whatever GCP permissions your personal account holds. If your account has broad project access, a bug in local code could affect real production resources. To test with narrower permissions that match production, impersonate a service account instead of using your user identity directly.

For more accurate local testing that mirrors what will happen in production, you can impersonate a service account without creating a key file:

# Run local code as if it were a specific service account
gcloud auth application-default login \
  --impersonate-service-account=backend-api@my-project.iam.gserviceaccount.com

This requires the Service Account Token Creator role on the target account. No long-lived key file is created.

Production on GCP

In production, attach a service account to every GCP resource that needs to call GCP APIs. The platform provides credentials automatically via the metadata server. Your application code changes nothing. Application Default Credentials finds the attached service account without any additional configuration.

# Attach a service account to a Cloud Run deployment
gcloud run deploy my-service \
  --region=us-central1 \
  --service-account=backend-api@my-project.iam.gserviceaccount.com \
  --image=gcr.io/my-project/my-service

# Attach a service account to a VM at creation time
gcloud compute instances create my-vm \
  --zone=us-central1-a \
  --service-account=backend-api@my-project.iam.gserviceaccount.com \
  --scopes=cloud-platform
The goal in production

No key files. No GOOGLE_APPLICATION_CREDENTIALS environment variables. No credentials in your application code. Just an attached service account and Application Default Credentials doing the work invisibly.

Application Default Credentials

Application Default Credentials (ADC) is the mechanism GCP client libraries use to find the right identity to authenticate as. Your code does not specify credentials directly. The library calls ADC, and ADC works through a lookup chain to find what is available.

The lookup order:

  1. The GOOGLE_APPLICATION_CREDENTIALS environment variable: if set, ADC uses the key file it points to
  2. Credentials from gcloud auth application-default login: used for local development with your user identity
  3. The service account attached to the running GCP resource: the metadata server provides the token automatically
  4. The default service account of the GCP environment, if present

On a VM or Cloud Run service with an attached service account, ADC skips the first two steps and resolves the attached account through the metadata server. No environment variables, no key files, no credential configuration in your application code.

# For local development: set your user identity as the ADC source
gcloud auth application-default login

# Check which identity ADC is currently using
gcloud auth application-default print-access-token

# For local testing that mirrors production: impersonate a service account
gcloud auth application-default login \
  --impersonate-service-account=backend-api@my-project.iam.gserviceaccount.com
Two gcloud auth commands, two different purposes

gcloud auth login authenticates the gcloud CLI so you can run gcloud commands. gcloud auth application-default login sets the credentials GCP client libraries use inside your application code. For local development, run both. On GCP infrastructure with an attached service account, neither is needed.

In production, always prefer an attached service account over setting GOOGLE_APPLICATION_CREDENTIALS to a key file. The attached account approach means there is no credential to store, rotate, or accidentally expose. If you hit authentication errors, see Troubleshooting Authentication Errors for the most common causes and fixes.

External workloads and Workload Identity Federation

When code runs outside GCP (in GitHub Actions, on AWS, on Azure, or on-premises) it cannot use an attached service account because there is no GCP infrastructure to attach to. The traditional workaround was to create a service account key file and store it as a secret in the external system.

Workload Identity Federation eliminates the need for key files by mapping an external identity to a GCP service account:

  1. The external workload presents its own credential (a GitHub Actions OIDC token, an AWS IAM role, a Kubernetes service account token)
  2. GCP verifies the external credential against a configured identity pool
  3. GCP issues a short-lived GCP access token for the mapped service account
  4. The workload uses that token to call GCP APIs. No key file was created or stored.
# Create a Workload Identity Pool for GitHub Actions
gcloud iam workload-identity-pools create "github-pool" \
  --project=my-project \
  --location="global" \
  --display-name="GitHub Actions Pool"

# Allow a specific repository's workflow to impersonate a service account
gcloud iam service-accounts add-iam-policy-binding \
  deploy-bot@my-project.iam.gserviceaccount.com \
  --project=my-project \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/attribute.repository/my-org/my-repo"
Prefer federation over key files for external workloads

A key file stored in GitHub Actions secrets is a long-lived credential that does not expire automatically. A Workload Identity Federation token is short-lived, scoped to a single workflow run, and leaves no permanent credential anywhere. If your CI/CD runs outside GCP, set up federation before reaching for a key file. See Service Account Keys Explained for a comparison of all credential options.

Best practices

  • Humans use user identities. Workloads use service accounts. Keep the two identity types completely separate. Never use a personal account for automation, and do not grant service accounts interactive Console access.

  • One service account per workload. A Cloud Run service and the CI/CD pipeline that deploys it should have separate service accounts. This limits the blast radius of any compromise and keeps access auditing straightforward.

  • Apply least privilege. Grant each service account only the IAM roles it needs to function. A workload that reads from Cloud Storage should have roles/storage.objectViewer, not roles/editor. See Principle of Least Privilege for a practical guide.

  • Prefer attached identities over key files. If your code runs on GCP, attach a service account to the compute resource. This removes the entire class of credential-file vulnerability.

  • Use Workload Identity Federation for external workloads. GitHub Actions, AWS workloads, and on-premises pipelines should use federation rather than storing a service account key file as a secret.

  • Use impersonation instead of key files for testing. To test what a service account can do, use gcloud —impersonate-service-account rather than downloading a key. See Service Account Impersonation for setup instructions.

  • Audit access regularly. Service account roles accumulate. Review what each service account can access quarterly and check for key files that are no longer in use with gcloud iam service-accounts keys list.

  • Separate human and workload access patterns. Do not grant a service account the same broad project-level role you might grant a human admin. Service accounts should have narrower, resource-specific permissions matched to exactly what the workload does.

Frequently asked questions

What is the difference between a user identity and a service account in GCP?

A user identity (Google Account or Cloud Identity account) represents a human. It authenticates with a password and MFA and is managed outside GCP. A service account represents a non-human workload: an application, a VM, a pipeline. It has no password and authenticates automatically via short-lived tokens. The rule is simple: humans get user identities, automation gets service accounts.

Should a CI/CD pipeline use a user account or a service account?

Always a service account. A user account is tied to an individual. If that person changes teams or leaves, the pipeline breaks. A service account belongs to the project, can be granted only the permissions the pipeline needs, and keeps working regardless of team changes. Use Workload Identity Federation to avoid creating a key file.

Can a human use a service account?

Not interactively. Service accounts have no password and cannot use browser-based OAuth login flows. However, a human with the roles/iam.serviceAccountTokenCreator role can impersonate a service account using gcloud --impersonate-service-account to generate a short-lived token. This is the correct way to test what a service account can do without creating a key file.

What is the safest way for code outside GCP to authenticate to Google Cloud?

Workload Identity Federation. It lets an external identity (a GitHub Actions OIDC token, an AWS IAM role, a Kubernetes service account) exchange for a short-lived GCP access token. No key file is created or stored. This is significantly safer than downloading a service account key file and storing it in CI environment variables.

Do I need both gcloud auth login and gcloud auth application-default login?

For local development, yes. They serve different purposes. gcloud auth login authenticates the gcloud CLI itself, so you can run gcloud commands. gcloud auth application-default login sets the credentials that GCP client libraries (Python, Go, Node.js) use in your application code. On GCP infrastructure with an attached service account, neither is needed: Application Default Credentials finds the service account automatically via the metadata server.

Last verified: 21 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.