Eliminating Service Account Keys: Implementing Workload Identity Federation in Google Cloud
Abstract
Automated Continuous Integration and Continuous Deployment (CI/CD) pipelines interacting with Google Cloud Platform (GCP) historically relied on long-lived Service Account private keys (.json credential files) stored in external Version Control System (VCS) secrets. Empirical cloud security forensics demonstrate that static Service Account keys are among the highest-risk credential types: they possess no default expiration, are vulnerable to build-log exposure, and cannot be centrally invalidated without breaking active pipelines.
This article covers the architectural and cryptographic implementation of Workload Identity Federation (WIF) in Google Cloud. We analyze the OpenID Connect (OIDC) token exchange protocol executed by Google Cloud Security Token Service (STS), evaluate the distinction between direct principalSet resource bindings and Service Account impersonation, dissect the critical role of CEL-based attribute_condition filters, and reference the production policy codified in GCP-IAM-001: Enforce Workload Identity Federation for VCS CI/CD Connections to GCP.
1. Threat Model: Static Service Account JSON Key Exposure
In Google Cloud IAM, creating a user-managed Service Account key produces a 72-byte cryptographic RSA private key encoded inside a JSON payload. Once issued, this key remains valid until explicitly deleted via API or Cloud Console (often lasting years). In enterprise environments, relying on static keys introduces four critical failure modes:
1.1 Log Aggregation & Environment Reflection
Modern build systems execute complex dependency pipelines where debugging tools, test frameworks, or misconfigured container entrypoints dump process environments (printenv / env). Once dumped to standard output, plaintext Service Account keys are indexed by centralized observability pipelines, making them accessible to broad engineering tiers.
1.2 Multi-Tenant Fork-Based Ingestion
Workflows triggered on pull_request events from external forks can execute untrusted code in the build context. If repository secrets are exposed to untrusted pull requests without runner isolation, threat actors can exfiltrate the JSON key directly to external Command & Control (C2) servers.
1.3 Upstream Supply Chain Compromise
Build steps execute package managers (npm, pip, cargo, go) that pull external dependencies. A malicious package executing in pre- or post-install scripts has full access to the runner's process memory, enabling silent exfiltration of all configured secrets.
1.4 Post-Decommission Zombie Credentials
When repositories or application components are decommissioned, their associated Service Account keys frequently remain active in GCP IAM. Without automated expiration, abandoned keys create persistent, unmonitored footholds in enterprise landing zones.
2. Technical Protocol: Workload Identity Federation Flow
Google Cloud Workload Identity Federation replaces static keys by establishing asymmetric cryptographic trust between an external identity provider (such as GitHub Actions or GitLab CI) and Google Cloud STS.
Protocol Execution Phases:
- OIDC Token Minting: When a workflow job triggers with
id-token: writepermissions, the GitHub Actions runner requests a cryptographically signed JSON Web Token (JWT) fromhttps://token.actions.githubusercontent.com. - STS Endpoint Resolution: The runner submits the token to the Google Cloud Security Token Service (
sts.googleapis.com) specifying the Workload Identity Pool and Provider identifier. - Cryptographic Validation: Google STS validates the issuer (
iss), audience (aud), and cryptographic signature against GitHub's public JSON Web Key Set (/.well-known/jwks.json). - Attribute Mapping & Condition Verification: STS extracts the configured claims from the JWT and evaluates the Common Expression Language (CEL)
attribute_condition. - Credential Generation: Upon validation, STS returns a temporary Google OAuth2 access token valid for up to 3,600 seconds.
3. The Security Boundary: Attribute Conditions
A widespread architectural misconfiguration in Workload Identity Federation is omitting the Attribute Condition (attribute_condition).
When a Workload Identity Pool Provider is created without an attribute condition, any GitHub Actions workflow in the world can present a valid GitHub OIDC token and exchange it for a federated Google credential if they know your Project Number and Pool ID.
The Decoded GitHub OIDC Claims Payload:
Enforcing Strict Attribute Conditions
In your Workload Identity Pool Provider configuration, you must define an attribute_condition that restricts token exchange to your specific organization or repository:
4. Production GitHub Actions Implementation
Below is the hardened production GitHub Actions workflow configuration utilizing google-github-actions/auth@v3:
5. Organizational Governance: Enforcing Key Disablement
To ensure that teams cannot bypass Workload Identity Federation by generating static Service Account keys, security architects must enforce the Google Cloud Organization Policy constraint:
Applying this constraint globally blocks all calls to CreateServiceAccountKey, preventing engineers and automation scripts from generating user-managed private keys and cementing Workload Identity Federation as the sole compliant authentication path.
Conclusion & Implementation Reference
Workload Identity Federation transforms CI/CD authentication from a high-risk static secret model into an auditable, ephemeral zero-trust architecture. By enforcing cryptographically validated OIDC tokens, scoping access via CEL attribute_condition expressions, and applying preventative Organization Policies, organizations eliminate private key exfiltration vectors across their entire Google Cloud footprint.
For the formal control specification, automated audit CLI scripts, and detection logic, refer to:
š GCP-IAM-001: Enforce Workload Identity Federation for VCS CI/CD Connections to GCP
š AWS-IAM-005: Enforce OIDC for VCS CI/CD Connections to AWS