DARINORCold Lab

// Field note

Workload Identity Federation for AI Agents: Kill the Static Key

By
8 min read
#workload-identity#agentic-ai#oidc#security

Workload Identity Federation for AI Agents: Kill the Static Key

The API key is the weakest part of any agent stack, and the data keeps proving it. GitGuardian's 2026 State of Secrets Sprawl report counted 28.65 million new hardcoded secrets added to public GitHub commits in 2025 — a 34% jump, the largest single-year increase they've recorded — and AI service secrets specifically grew 81% year over year, to 1.27 million. Claude Code-assisted commits leaked secrets at a 3.2% rate versus a 1.5% baseline across all public commits. The agents aren't just writing the code anymore. They're the ones leaking the keys.

The fix isn't a better secret manager. It's removing the secret entirely.

Workload identity federation (WIF) is the mechanism that lets a workload prove its identity in one environment and receive credentials in another — using short-lived OpenID Connect (OIDC) tokens instead of stored secrets. It's been the standard for CI/CD and Kubernetes for years. What changed in 2026 is that the AI API layer finally caught up: Anthropic shipped workload identity federation for the Claude Platform in June, meaning every major AI API surface now has a path off static keys. If your agents still authenticate with a key in an environment variable, you're running the old pattern on purpose.

What WIF actually is

The exchange is simple. Your workload's platform — an AWS IAM role, a Kubernetes service account, a GitHub Actions runner — issues an OIDC token. The workload presents that token to the target system, which validates it against a trust relationship you configured in advance, and returns a short-lived, scoped credential. The two standards doing the heavy lifting are the JWT bearer grant (RFC 7523) and OAuth token exchange (RFC 8693).

The canonical example is Kubernetes. A pod gets a projected service account token — a JWT with an iss identifying the cluster, a sub like system:serviceaccount:prod:worker, an audience, and an expiry measured in hours, not years. The cluster signs it, the cloud provider trusts the cluster's OIDC issuer, and the pod exchanges that token for cloud credentials scoped to exactly one service account. No key was ever written to disk, no secret was ever rotated, and the token dies with the workload's need for it.

That's the pattern. The interesting part is what happens when the workload is an agent.

Why agents break the old model

Static machine identities run the same job the same way every time. Agents don't. They discover and call tools at runtime, cross trust boundaries in non-deterministic order, and act on behalf of a human user whose permissions need to be reflected in every downstream call. A static API key can't represent any of that:

  • Dynamic tool access. Pre-provisioning static credentials for every tool an agent might call is impractical, and over-permissioning the ones you do provision recreates the exact sprawl problem WIF exists to solve.
  • Delegated authority. The credential an agent uses downstream needs to carry both the agent's own identity and the user's authorized permissions. A static key carries neither.
  • Ephemeral execution. Agent lifecycles in containerized or serverless environments can be seconds. A credential that exists only for the duration of a token is the only kind that matches that lifecycle — no rotation, no revocation, no secret to manage after the task dies.

The first hop — the agent proving it runs in your infrastructure — is exactly what WIF solves. That's the hop where the static key currently lives, and it's the one you can eliminate today.

The five-step migration

Step 1 — Inventory where agents hold static credentials.

Start with the boring part: find the keys. Agent configs are the new leak surface — GitGuardian found 24,008 unique secrets in MCP-related configuration files on public GitHub, including 2,117 valid credentials. Grep your agent configs, .env files, CI secrets, and MCP server configs for sk-ant-, sk-proj-, and anything that looks like a long-lived token. The AI Agent Config Checker runs this scan for you — it flags static credentials sitting in agent and MCP configs before you start migrating.

Step 2 — Pick the identity your agent already has.

You don't create a new identity for WIF. You use the one the platform already gave the workload: a Kubernetes service account, an AWS IAM role, a GitHub Actions OIDC token, an Azure managed identity. The agent's proof of identity is its runtime context — its namespace, its role, its repository — verified cryptographically by the platform that runs it. If your agent runs in a cluster, it already has a service account token. If it runs in CI, the runner already has an OIDC endpoint. The identity exists; you're just going to start using it.

Step 3 — Configure the trust relationship.

This is the only real setup work, and it's the same shape everywhere. On the target side you register three things: the issuer (the OIDC provider whose signatures you trust), the service account (the non-human identity the token will act as), and the rule (which claims must match for a token to map to that service account). Anthropic's Claude Platform implementation is a clean example: a federation rule binds an external identity to a service account, and when a workload requests access, the platform verifies the signed OIDC token, matches its claims against your rules, and issues a short-lived access token bounded by the service account's roles. Every exchange lands in the audit log against that service account.

The rule is where least privilege lives. Match on the sub prefix, the audience, or a CEL expression — the same way an AWS trust policy conditions sts:AssumeRoleWithWebIdentity on token.actions.githubusercontent.com:sub matching repo:octo-org/octo-repo:*. A token from the wrong namespace, the wrong repo, or the wrong environment should fail the match and get nothing.

Step 4 — Wire the exchange into the harness.

The SDKs handle the exchange and refresh loop for you. Your application code constructs the client with no API key, and the SDK posts the platform JWT to the token endpoint, gets back a short-lived access token, and refreshes it before expiry. The minted token's lifetime is bounded by the upstream JWT — Anthropic caps it at the lesser of the rule's configured lifetime and twice the remaining life of the identity token you presented, so a compromised upstream credential can't extend into unlimited downstream access.

One footgun to know about: environment-variable precedence. If ANTHROPIC_API_KEY is still set anywhere in the workload's environment, it silently wins over federation. The migration isn't done when the WIF code path works — it's done when the key is gone.

Step 5 — Kill the static key.

Remove the key from CI secrets, container environments, and shell profiles. Verify the federated path is what's actually being used — check the SDK's auth status from inside the workload, not from your laptop. Then revoke the key in the console. The key that no longer exists can't leak, can't be rotated, and can't be found by the next scanner.

What WIF doesn't fix

Be honest about the boundaries, because they're where the next incidents will live.

It covers one destination at a time. Anthropic has WIF. OpenAI and most other AI vendors still use API keys, and your internal services probably have service accounts with passwords set in 2021. Securing the Claude connection is real progress; it's not a workload access program.

Federation is only as strong as your IdP configuration. Anthropic's own docs say it plainly: federated authentication is only as strong as the upstream identity provider that signs the JWT. Kubernetes service account tokens are scoped to the namespace by default, not the pod. If your service account is scoped too broadly, WIF will faithfully mint a valid token for the wrong workload. The attestation problem — proving a specific workload is who it claims to be — has to be solved at the IdP layer, and WIF assumes it's already done.

Delegated authority still needs an identity layer. WIF solves the first hop: the agent proves it runs in your infrastructure. It doesn't solve what happens after — how the agent gets a scoped credential for your identity platform, how that credential gates access to downstream services, and how each step traces back to the user who delegated the task. The cloud providers are building agent-aware identity services for exactly this gap, and they're each tightly coupled to their own ecosystem.

The pattern

Every agent has an identity already. The platform that runs it — the cluster, the CI runner, the cloud account — can prove it cryptographically. Workload identity federation is just the act of using that proof instead of a key. The migration is five steps, the first of which is finding the keys you're about to delete.

And when you're debugging the trust relationship — checking whether the sub claim actually matches your rule, whether the audience is right, whether the token you're presenting is the one you think it is — decode it. The JWT Decoder runs entirely in your browser, so you can inspect the claims of a real OIDC token without pasting it into a third-party site. That's the whole game: know what your agent is asserting, and make the trust rule match exactly that.

This site uses minimal cookies and local storage to keep features like the chat widget and games working. We do not use third-party tracking cookies. Privacy Policy