All resources
Guide/8 min read

How to give AI coding agents AWS and Google Cloud access with OIDC instead of stored keys

Published

Summary

A coding agent swaps a 15-minute OIDC token for AWS credentials, with no stored key. Real commands and output, what AWS rejected, and how other agents compare.

A coding agent that deploys code, reads logs, or checks a bucket needs cloud access. The usual way to give it that is to paste an AWS access key or a Google service account file into its environment variables. Then anything the agent runs can read the key, including a bad dependency or instructions hidden in an issue it was asked to fix. If the key leaks, it keeps working until someone notices and rotates it.

OpenID Connect (OIDC) removes the stored key. The agent's machine asks for a signed token that says which organization, environment, and workspace it belongs to. AWS or Google Cloud checks the signature against the issuer's public keys, compares the token with a trust policy you set up once, and returns credentials that expire within the hour. GitHub Actions has worked this way for years, and several cloud coding agents now do too.

How an agent gets AWS credentials without a stored key

  1. 01

    Agent

    Workspace

    Asks for a token for one service

    replicas identity token --audience sts.amazonaws.com

  2. 02

    Replicas

    api.replicas.dev

    Signs a token that lasts 15 minutes

    sub: org:…:env:…:workspace:…

  3. 03

    AWS STS

    Your AWS account

    Checks the signature, audience and subject

    Against the keys at /.well-known/jwks.json and your role’s trust policy

  4. 04

    Agent

    Workspace

    Gets temporary credentials for one role

    Keys that start with ASIA and expire in 1 hour

In the workspace

A CLI profile that runs the exchange, and no AWS key

In your AWS account, once

An OIDC provider for api.replicas.dev and a role whose trust policy names your organization

Google Cloud and your own APIs follow the same steps, with Google’s STS or your service in step 3.

The steps below run that exchange with Replicas workspace identity and show the real output.

How we tested

An AI agent, Claude Code running in a Replicas workspace, ran every command on this page on November 7, 2026 and wrote the guide. A person at Replicas reviewed it before it was published.

The AWS exchange used our own AWS account and an IAM role we had made earlier to test this feature. The role has no permissions attached, so it can prove who it is and do nothing else. We created no AWS resources for this guide. We had no Google Cloud project to test with, so the Google Cloud exchange is marked as not run. In the output below, IDs, account numbers, and email addresses are replaced with placeholders, and no full token is shown.

Step 1: Get a token and check its signature

Inside a workspace, the replicas CLI asks for a token for one audience, which is the service that will receive it. For AWS, the audience is sts.amazonaws.com:

That took 0.9 seconds. A JWT has three base64url parts: a header, the claims, and a signature. Decoded, the first two were:

exp minus iat is 900 seconds, so the token lasts 15 minutes. AWS trust policies match on sub. The other claims are for services that can read them, such as Google Cloud and your own APIs. The docs describe each one.

Anyone can write JSON that decodes like this, so the claims mean nothing until the signature checks out. The issuer publishes its public keys at fixed addresses:

jwks.json held one 2048-bit RSA key with the same kid as the token. We converted it to PEM and checked the signature with OpenSSL, without any Replicas code:

Changing one character of signed.txt gave Verification failure. AWS, Google, and your own service all run this same check.

Step 2: Trust the issuer in AWS

Someone with IAM access does this once. We didn't repeat it for this guide because the provider and role already existed in our account. AWS's guide covers the console steps. It comes down to two things:

  1. An IAM OIDC identity provider with the URL https://api.replicas.dev and the audience sts.amazonaws.com.
  2. A role whose trust policy accepts tokens from that provider. This is the trust policy on the role we used, with our IDs replaced and a second pattern for an older token format left out:

For a provider like this, a trust policy can match the token's aud and sub, but not custom claims such as creator_email (AWS). So sub is where you narrow access. Put an environment ID in place of env:* to accept only workspaces from that environment. What the agent can do once it has the role is set by the role's permission policies, as with any role. Ours has none.

Step 3: Exchange the token for AWS credentials

In the workspace, an AWS CLI profile runs the exchange whenever the CLI or an SDK needs credentials:

You can ask the agent to set this up in plain words, or put the command in the environment's start hook so every workspace starts with it. Any agent in the workspace uses the profile the same way, whether it's Claude Code, Codex, or a script, because it's an ordinary AWS CLI profile.

We removed the AWS keys from the shell first, so nothing else could be used:

The first call took 3.0 seconds, including the exchange. The second took 1.4 seconds, because the helper caches the credentials and only exchanges a new token when they have less than 15 minutes left. The cache is a file only the workspace user can read:

Keys that start with ASIA are temporary. Long-lived IAM user keys start with AKIA. These expired one hour after the exchange.

The helper calls STS AssumeRoleWithWebIdentity. You can make the same call yourself, and it needs no AWS credentials:

What AWS accepted and rejected

We then sent tokens and requests that should fail. AWS refused all of them except the expired token, which it accepted for up to five minutes after it expired:

What we sentWhat AWS returned
A token minted for https://api.example.com instead of sts.amazonaws.comInvalidIdentityToken
A real token with sub edited to another organizationInvalidIdentityToken, because the signature no longer matched
A token that had expired 2 minutes 20 seconds earlierNew credentials. AWS accepted it
The same token, 4 minutes 50 seconds after it expiredNew credentials again
The same token, 5 minutes 47 seconds after it expiredExpiredTokenException: Token expired: current date/time 1794040233 must be before the expiration date/time 1794040186
A valid token with --source-identity, on a role whose trust policy doesn't allow sts:SetSourceIdentityAccessDenied
aws s3 ls with the role's credentialsAccessDenied: no identity-based policy allows s3:ListAllMyBuckets

The token proves which workspace is calling, and the role decides what that workspace may do. Ours allows nothing, so S3 refused. If you turn on source identity, AWS records the workspace ID on every action in CloudTrail. The role's trust policy has to allow it first, as the sixth row shows.

The expired token surprised us. The "current date/time" in AWS's error was exactly 300 seconds behind the real time, which suggests STS allows five minutes for clock differences. At AWS, a token that lasts 15 minutes can be exchanged for up to 20, and the credentials it returns last another hour. We found no AWS page that documents this window.

Google Cloud (not run end to end)

Google Cloud uses Workload Identity Federation. Someone with IAM access creates a workload identity pool with an OIDC provider for https://api.replicas.dev, maps google.subject to assertion.workspace_id, adds a condition such as assertion.organization_id == '<organization_id>', and grants roles. Unlike AWS, Google's conditions can read any claim, so you can also limit access by environment_id or creator_email. Our docs have the commands.

In the workspace, gcloud and Google's client libraries run a command to get a token whenever they need one. This is the command they run, and what it printed for us:

That is the format Google expects from an executable credential source. We had no Google Cloud project for this test, so we didn't send the token to Google's STS.

Your own API or MCP server

The same token works for any service that can check a JWT. As a stand-in for an internal deploy API, we ran this Node server in the workspace. It has no dependencies, keeps the issuer's keys for 5 minutes, and fetches them again sooner when a token names a key it doesn't have:

We saved it as server.mjs and started it with our organization ID as the only allowed organization:

The agent called it with a fresh token for that audience:

What we sentResponse
A token for https://deploys.internal.example200 with the workspace, environment, and creator's email
No token401 Missing token
A token minted for https://api.example.com401 Wrong audience
A real token with organization_id edited401 Invalid signature
A token with "alg": "none" and no signature401 Invalid signature
A valid token, with our organization left off the allowlist401 Organization not allowed
A token that had expired 53 seconds earlier401 Expired or not yet valid

For an MCP server, you don't need the CLI. When you add an HTTP MCP server to a Replicas environment, choose Workspace identity token as its authentication, and Replicas attaches a current token to every request (docs). The server checks it the same way. We didn't test the MCP path for this guide.

How other cloud coding agents get cloud credentials

Every cloud coding agent we checked can store secrets and hand them to the agent's machine. Five of the nine below also issue their own OIDC token, so you can set up keyless access to AWS or Google Cloud the way this guide does, and GitHub Copilot can use GitHub Actions' token. If you use more than one agent, each one with its own issuer needs its own provider and trust policy in your cloud account.

We checked each vendor's own docs on November 7, 2026. Agents are in alphabetical order:

AgentStored secretsOwn OIDC token
Claude Code on the webEnvironment variables, which anyone who uses the environment can read. Network secrets, which Anthropic's proxy adds to requests for hosts you list, so the session never sees them (Anthropic)Not documented for Anthropic-hosted environments. Self-hosted environments, in beta on Team and Enterprise, run on your machines, where a wrapper script can provision short-lived credentials per session (Anthropic)
Codex cloudEnvironment variables, and network secrets that a proxy swaps in on HTTPS requests (OpenAI)Yes, set per environment. OpenAI lists supported services for AWS, Google Cloud, and Azure. RDS and Cloud SQL IAM logins, and Azure Resource Manager, Blob Storage, and Container Registry, are not yet supported (OpenAI)
Cursor cloud agentsSecrets as environment variables. Runtime secrets are redacted from transcripts and commits but can still be read in the terminal (Cursor)Yes. Issuer https://api.cursor.com, tokens last 5 minutes. AWS has a worked example. Google Cloud, Azure, and Vault are listed as compatible (Cursor)
DevinSecrets given to commands as environment variables when needed, scoped to the organization, a person, a repository, or a session (Cognition)Yes. Issuer https://app.devin.ai, with setup actions for AWS, Google Cloud, Vault, and JFrog. Token lifetime isn't published (Cognition)
FactoryPersonal and organization secrets, which become environment variables. Not available during environment builds (Factory)None documented
GitHub Copilot cloud agentAgents secrets, given to the agent as environment variables (GitHub)Through GitHub Actions. When the agent runs on Actions, its setup steps can request Actions' OIDC token. GitHub documents an Azure login this way (GitHub)
Google JulesRepository environment variables, turned on per task (Google)None documented
OnaOrganization, project, and user secrets (Ona)Yes. Issuer https://app.gitpod.io, with AWS and Google Cloud guides (Ona). Enterprise plan (Ona)
ReplicasEnvironment variables, which can also sync from Doppler or Infisical (Replicas)Yes. Issuer https://api.replicas.dev, tokens last 15 minutes. AWS and Google Cloud guides, and MCP servers. Team and Enterprise plans, and trials (Replicas)

Where Replicas falls short

Workspace identity is only on Team and Enterprise plans and trials. Our tokens last 15 minutes, three times as long as Cursor's 5, and an issued token can't be revoked before it expires. Our docs cover AWS and Google Cloud but not Azure, and we haven't tested Azure.

For an API that only accepts a fixed key, Replicas puts the key in an environment variable the agent can read. Claude Code on the web and Codex cloud can keep that kind of key in a proxy outside the agent's machine, and Replicas has no equivalent yet. The security page lists the controls Replicas does have, by plan.

What OIDC doesn't protect against

Short-lived tokens remove one risk: a long-lived key sitting in the agent's environment. They don't make the agent trustworthy, and they don't limit what it does with access you gave it.

RiskDoes a short-lived token help?What to do
The agent misuses access it was given, for example after reading instructions planted in an issueNo. It can do whatever the role allowsGive the role only what the task needs, read-only where you can. Use a separate role for each environment
Credentials are copied out of the workspace during a sessionPartly. AWS accepts the token for up to 5 minutes after it expires, and the credentials it returns last an hour. Both work from anywhere until thenIf you suspect a leak, revoke the role's active sessions in IAM
Anyone who can start a workspace in your organization gets a token that matches an organization-wide trust policyNoMatch one environment in sub, and limit who can use that environment
You remove someone's access, but they already have a tokenPartly. Replicas stops issuing tokens right away, but a token already issued works until it expiresArchive the workspace to stop new tokens, and revoke the role's sessions in AWS if it matters
Data the agent reads goes to its model providerNoDon't give the role access to data you can't send to your model provider. Our HIPAA guide covers where that data goes
A service only accepts a fixed API keyNoThat key still lives in the workspace. Scope it and rotate it

If you're rolling this out across a company, Replicas Enterprise adds dedicated or self-hosted deployment and SCIM provisioning. The workspace identity docs have the full setup for AWS, Google Cloud, MCP servers, and your own APIs.