Service Accounts vs User Accounts
In Google Cloud Platform (GCP), understanding the distinction and appropriate use cases for service accounts versus user accounts is fundamental for…
In Google Cloud Platform (GCP), understanding the distinction and appropriate use cases for service accounts versus user accounts is fundamental for robust security and operational efficiency. While both facilitate authentication and authorization, their intended purposes, management paradigms, and security implications differ significantly. This article will elaborate on these differences, best practices for their deployment, and mechanisms for secure credential management.
GCP uses Cloud Identity to manage both user and service accounts, providing a unified authorization model through Identity and Access Management (IAM). IAM policies, consisting of a principal, role, and resource, govern what actions any account can perform. The key differentiator lies in the nature of the principal: whether it represents a human identity or a programmatic identity.
User Accounts: Human Identities in GCP
User accounts in GCP represent individual human users. These accounts are typically managed through Google Workspace (formerly G Suite) or Cloud Identity. They authenticate using standard credentials like passwords, two-factor authentication (2FA), or federated identity providers (e.g., corporate SSO).
Authentication Methods for User Accounts
- Google Sign-In: Standard Google credentials (username/password, 2FA).
- Federated Identity: Integration with enterprise identity providers (IdP) like Active Directory Federation Services (AD FS), Okta, or Azure AD via SAML 2.0 or OpenID Connect (OIDC). This allows users to use their existing corporate credentials to access GCP.
- External Identity: For specific use cases, users can be granted access via external identities, managed by Cloud Identity.
Use Cases for User Accounts
User accounts are designed for interactive access to GCP resources via the Google Cloud Console, gcloud CLI, or API calls initiated by a human. Examples include:
- Cloud engineers performing infrastructure deployments and management.
- Developers writing and testing code that interacts with GCP services.
- Data scientists analyzing data in BigQuery or Cloud Storage.
- Auditors reviewing access logs and configurations.
Managing User Account Permissions
IAM roles are assigned directly to user accounts or to groups that user accounts are members of. Best practice dictates using groups (e.g., gcp-admins@example.com, devs@example.com) to manage permissions, simplifying administration and improving auditability. Roles should always adhere to the principle of least privilege.
Service Accounts: Programmatic Identities for Workloads
Service accounts are special types of Google accounts designed for non-human entities, such as virtual machines (VMs), Cloud Functions, Kubernetes Pods, or applications. They authenticate using cryptographically strong credentials managed by GCP, eliminating the need to embed user credentials in code or configuration files.
Authentication Methods for Service Accounts
Unlike user accounts, service accounts typically don't have passwords. They authenticate primarily using:
- Short-lived Access Tokens: The most secure and common method. When a workload (e.g., a Compute Engine VM) is assigned a service account, the metadata server on that VM can automatically acquire short-lived OAuth 2.0 access tokens. These tokens are valid for a short duration (typically 1 hour) and are automatically refreshed.
- Service Account Keys (Legacy/Specific Use Cases): These are JSON or P12 files containing a private key. While still supported, they represent long-lived credentials and pose significant security risks if mishandled. Their use should be minimized and, where necessary, strictly managed.
Service Account Key Types and Security Implications
GCP defines two types of service account keys:
- Google-managed keys: These are the keys automatically rotated and managed by GCP when a service account is attached to a resource (e.g., a Compute Engine instance, Cloud Run service, or GKE node pool). These are highly secure as their private key material is never exposed directly.
- User-managed keys: These are keys generated by a user and downloaded as a JSON or P12 file. These keys are long-lived and require manual rotation. If compromised, they can grant persistent access to GCP resources. Never share or download long-lived keys unless absolutely necessary for specific integration patterns (e.g., on-premises applications connecting to GCP APIs, or third-party tools that don't support Workload Identity Federation). If user-managed keys are necessary, implement a strict rotation policy (at least quarterly) and monitor their usage.
Secure Credential Management for Service Accounts
The core principle for service accounts is to avoid long-lived, manually managed credentials whenever possible.
- Attached Service Accounts: For GCP compute resources (Compute Engine, GKE, Cloud Run, App Engine, Cloud Functions), assign a service account directly to the resource. The underlying compute instance or service will then automatically obtain short-lived credentials via its metadata server. This is the preferred method.
- Workload Identity Federation: For workloads running outside GCP (e.g., on-premises Kubernetes, Azure VMs, AWS EC2 instances), Workload Identity Federation allows external identities to impersonate a GCP service account. This eliminates the need to download and manage service account keys, as the external identity provider handles authentication, and GCP trusts tokens issued by it.
- Secret Manager: If a specific application or integration requires a user-managed service account key (e.g., for an on-premises application that can't use federation), store the key in Google Secret Manager and grant the consuming application's service account (or the external workload via federation) permission to access that secret.
# Example: Granting a Compute Engine VM's service account access to Secret Manager
# 1. Create a service account for the VM
gcloud iam service-accounts create my-vm-service-account --display-name "Service Account for My VM"
# 2. Grant permissions to the service account (e.g., roles/storage.objectViewer)
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:my-vm-service-account@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"
# 3. Create a VM instance and assign the service account
gcloud compute instances create my-instance \
--zone=us-central1-a \
--machine-type=e2-medium \
--service-account=my-vm-service-account@YOUR_PROJECT_ID.iam.gserviceaccount.com \
--scopes=https://www.googleapis.com/auth/cloud-platform # Or more granular scopes
# Example: Workload Identity Federation for an OIDC provider (e.g., GitHub Actions)
# 1. Create an Identity Provider pool
gcloud iam workload-identity-pools create github-pool \
--project=YOUR_PROJECT_ID \
--display-name="GitHub Actions Workload Identity Pool"
# 2. Create an Identity Provider in the pool (replace values as needed)
gcloud iam workload-identity-pools providers create-oidc github-provider \
--project=YOUR_PROJECT_ID \
--workload-identity-pool=github-pool \
--display-name="GitHub Actions OIDC Provider" \
--issuer-uri="https://token.actions.githubusercontent.com" \
--attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository"
# 3. Create a GCP Service Account to be impersonated
gcloud iam service-accounts create github-sa \
--project=YOUR_PROJECT_ID \
--display-name="Service Account for GitHub Actions"
# 4. Grant the external identity (e.g., a specific GitHub repository) permission to impersonate the SA
gcloud iam service-accounts add-iam-policy-binding github-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com \
--project=YOUR_PROJECT_ID \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/YOUR_PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/attribute.repository/YOUR_GITHUB_ORG/YOUR_REPO_NAME"
# In GitHub Actions workflow:
# jobs:
# build-deploy:
# permissions:
# id-token: write
# contents: read
# steps:
# - id: 'auth'
# uses: 'google-github-actions/auth@v2'
# with:
# workload_identity_provider: 'projects/YOUR_PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/providers/github-provider'
# service_account: 'github-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com'
# - name: 'Use gcloud CLI'
# run: 'gcloud storage ls gs://my-bucket-from-github-actions'
Key Differences and Best Practices
| Feature | User Account | Service Account |
|---|---|---|
| Principal Type | Human user | Application, workload, VM, service |
| Authentication | Password, 2FA, SSO | Short-lived tokens (managed), or long-lived keys (user-managed, discouraged) |
| Primary Use Case | Interactive console/CLI access, human-driven API calls | Programmatic access, inter-service communication |
| Key Management | Managed by user/IdP | GCP-managed (preferred) or user-managed (discouraged) |
| Access Revocation | Disable user, remove from group, modify IAM | Delete SA, modify IAM, disable SA keys |
| IAM Principal Format | user:email@example.com, group:group@example.com |
serviceAccount:email@project.iam.gserviceaccount.com |
Best Practices for Both Account Types
- Least Privilege: Grant accounts only the permissions necessary to perform their specific tasks. This is paramount for both user and service accounts. Use custom roles if predefined roles are too broad.
- No roles/owner: Avoid granting
roles/owner(orroles/editorfor service accounts) on production projects. These roles grant excessive permissions and create significant security risks. For human users, use project-level roles likeroles/resourcemanager.projectIamAdminor more granular roles combined with conditional IAM. - Regular Audit: Periodically audit IAM policies using Cloud Audit Logs and Cloud Asset Inventory. Look for overly permissive roles, dormant accounts, or unnecessary user-managed keys.
- Separate Environments: Use distinct service accounts and, ideally, projects for different environments (e.g., development, staging, production) to limit blast radius in case of compromise.
Common Pitfalls and Troubleshooting
- Over-privileged Service Accounts: Granting
roles/editororroles/ownerto service accounts is a common mistake. This allows a compromised workload to potentially control the entire project. Always narrow down permissions to the specific resources and actions required. Use tools like Policy Intelligence to get role recommendations. - Downloading and Storing Service Account Keys Locally: This is a major security vulnerability. If a user-managed key file is downloaded, it should be treated with the same criticality as root credentials. Implement key rotation and ensure it's not committed to source control or exposed publicly. If you find yourself in this situation, re-evaluate if Workload Identity Federation or an attached service account is a viable alternative.
- Forgetting to Enable APIs: Even with the correct IAM permissions, a service account (or user account) cannot access a GCP service if its API is not enabled for the project. Check the "APIs & Services" dashboard.
- Incorrect Scopes on Compute Engine: When creating a Compute Engine VM, the
--scopesflag determines what OAuth scopes the instance's service account can request. Even if the service account has IAM roles, if the required API scope (e.g.,https://www.googleapis.com/auth/devstorage.read_onlyfor Cloud Storage) is not included in the VM's scopes, the application running on the VM will be denied access. The--scopes=https://www.googleapis.com/auth/cloud-platformprovides broad access, but it's better to specify granular scopes. - Service Account Impersonation Issues: If you're using Workload Identity Federation or service account impersonation, ensure the "Workload Identity User" role (
roles/iam.workloadIdentityUser) is granted correctly to the principal that needs to impersonate the service account. - Dormant Accounts: Regularly audit for service accounts or user accounts that are no longer in use but still retain permissions. Delete or disable them to reduce the attack surface.