Killing static cloud keys with workload identity federation
Cloud Security
Static access keys in CI pipelines and cross-cloud workloads are the biggest preventable credential exposure most companies still have. OIDC-based workload identity federation removes them entirely.
By Arjun Raghavan, Security & Systems Lead, BIPI · March 30, 2024 · 8 min read
We do an exposure audit at the start of most engagements. The number one credential leak we still find in 2026 is a static AWS access key sitting in a GitHub Actions secret, or a GCP service account key JSON in a CircleCI environment variable. These keys live for years, they have broad permissions, and they get rotated approximately never. Workload identity federation lets you delete them entirely and use short-lived OIDC tokens instead.
The pattern works the same across AWS, Azure, and GCP, with cloud-specific gotchas. Once it is in place, your CI pipeline cannot leak credentials because there are no credentials to leak.
How OIDC federation works in one paragraph
Your CI provider (GitHub Actions, GitLab CI, CircleCI, Bitbucket) issues an OIDC ID token to each job. The token is signed by the CI provider, contains claims about the repo, branch, and workflow, and lives for a few minutes. The cloud provider trusts the CI provider's OIDC issuer and exchanges the ID token for short-lived cloud credentials. No long-lived secrets are stored anywhere; the trust is in the public OIDC keys and the claim conditions you set on the cloud-side role.
AWS: OIDC provider plus role trust policy
Create an IAM OIDC identity provider for token.actions.githubusercontent.com (or your CI of choice). Create an IAM role with a trust policy that requires the OIDC token's sub claim to match a specific repo and branch: repo:my-org/my-repo:ref:refs/heads/main. In GitHub Actions, the aws-actions/configure-aws-credentials action exchanges the OIDC token for STS credentials. Done. No access keys, no rotation, no secret scanner findings.
GCP: workload identity pools
Workload Identity Federation in GCP uses a Workload Identity Pool that maps external OIDC subjects to a service account via attribute conditions. The pool has a provider configured for the CI's OIDC issuer; the binding to a service account is a roles/iam.workloadIdentityUser grant. The CI then uses google-github-actions/auth or equivalent to fetch a short-lived service account token. The historical service-account-key download flow becomes unnecessary.
Azure: federated credentials on app registrations
Azure's version is Federated Identity Credentials on a Microsoft Entra ID app registration or user-assigned managed identity. Configure the issuer URL and subject identifier on the app registration to match your CI's OIDC token claims. The CI exchanges its OIDC token for an Entra ID access token via the standard client credentials flow with a federated assertion. Roles are assigned to the service principal in the normal way.
Cross-cloud workloads: same pattern
A common scenario is a workload running on GCP that needs to read from an S3 bucket, or an EKS pod that needs Azure Storage. Solve it the same way: GCP service account or EKS pod identity issues an OIDC token, AWS or Azure trusts that issuer via federation. No keys cross the trust boundary. This pattern works equally well for SaaS-to-cloud trust where a third-party service supports OIDC token-based authentication; we have done it with Snowflake, Databricks, and Datadog without ever issuing them a long-lived cloud credential.
Audit considerations
Federated tokens show up in cloud audit logs with the federated identity as the principal, not the role. CloudTrail records the AssumeRoleWithWebIdentity call and the subsequent activity under the assumed role's session name; we tag the session name with the GitHub run ID so we can trace cloud actions back to a specific workflow run. GCP and Azure expose similar metadata. Build the SIEM correlation queries before you migrate, not after, so the loss of the static-key audit trail is replaced by something better, not nothing.
Migration path that does not break Friday
Pilot in a non-production repo for two weeks. Run federation alongside the existing static keys, with the pipeline preferring federation. After two weeks, delete the static keys from the test repo and confirm nothing breaks. Roll out to staging repos, then production, in batches of 5-10 repos a week. Maintain a short-lived bypass mechanism (a manual approval to issue a temporary key) for the first month in case of issuer outages, then retire it.
- Inventory every long-lived cloud key in your CI providers, partner integrations, and SaaS connections
- Pick a pilot repo with low blast radius and good test coverage
- Configure the cloud-side OIDC trust with strict claim conditions
- Run pipelines in dual-mode for two weeks; compare audit logs
- Delete static keys, monitor for failures, repeat across the estate
Static cloud keys are now an anti-pattern, not a default. The migration is finite work, the security benefit is permanent, and your secret-scanner queue stops being full of cloud credentials. There is rarely a better high-leverage cloud security project than this one.
Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.