[FEATURE] Issue an OIDC identity token to cloud sessions for keyless cloud provider auth
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Claude Code on the web supporting multiple github repos at the same time is a game changer for me, esp. when used along with Claude mobile app. OTOH, it has no way to obtain cloud provider credentials without a long-lived static secret. The docs state both halves of the gap explicitly:
- Static API tokens and credentials — Not available. "No dedicated secrets store exists yet." Environment variables are the only injection mechanism, and "both environment variables and setup scripts are stored in the environment configuration, visible to anyone who can edit that environment."
- Interactive auth like AWS SSO — Not supported. "SSO requires browser-based login that can't run in a cloud session."
The result is that the only sanctioned path to AWS, GCP, or Azure from a cloud session is pasting a long-lived access key into a plaintext, shared-visibility field. For anyone operating under a no-static-credentials policy — which is now the default posture for IaC work — that path is unusable, so infrastructure workflows can't move to cloud sessions at all.
This is not fixable with a secrets store. A secrets store protects a static credential; it doesn't remove it. The credential still exists, still needs rotation, and still grants standing access to a cloud account from a shared environment config. The underlying problem is that a cloud session has no verifiable identity — nothing signed that an external system can bind a trust policy to.
Concretely, this blocks:
- Running
pulumi preview/terraform planin-session so Claude can iterate against real drift and error output - Reading cloud state (
aws eks describe-cluster,kubectlagainst a managed control plane) to diagnose a problem Claude is being asked to fix - Any read-only cloud introspection during a task, even where no mutation is intended
Note that the network side is already solved. The Trusted allowlist includes *.amazonaws.com, *.api.aws, *.googleapis.com, and *.microsoftonline.com, so STS and the equivalent token endpoints are reachable today. The only missing piece is the token.
Proposed Solution
Issue each cloud session a short-lived, signed OIDC ID token, and publish a discovery document and JWKS endpoint so cloud providers can validate it. This is the same mechanism GitHub Actions exposes via id-token: write and ACTIONS_ID_TOKEN_REQUEST_URL.
Mechanism
sequenceDiagram
participant Session as Cloud session sandbox
participant Issuer as Anthropic OIDC issuer
participant STS as AWS STS / GCP STS / Entra ID
Session->>Issuer: GET token request (audience=sts.amazonaws.com)
Note over Session,Issuer: authenticated by the sandbox's<br/>internal session identity, not a user secret
Issuer-->>Session: signed JWT (TTL ~15 min)
Session->>STS: AssumeRoleWithWebIdentity(JWT)
STS->>Issuer: fetch JWKS, verify signature
STS-->>Session: short-lived credentials
Note over Session: pulumi / aws CLI / kubectl<br/>pick these up ambiently
The session never holds a secret. The trust relationship lives in the customer's IAM policy, where it can be scoped, audited, and revoked independently of Anthropic.
Token claims
The value of this proposal depends on the claims being specific enough to write a tight trust policy against. Proposed set:
| Claim | Example | Purpose |
| --- | --- | --- |
| iss | https://oidc.claude.com | Discovery + JWKS root |
| sub | repo:acme/infra:env:production | Primary subject for IAM condition matching |
| aud | sts.amazonaws.com | Caller-specified, prevents token replay across providers |
| repository | acme/infra | Scope a role to one repo |
| repository_owner | acme | Org-level scoping |
| environment | production | Distinguish cloud environment configs |
| organization_id | <claude.ai org UUID> | Prevents cross-tenant confusion |
| actor | <claude.ai user id> | Attribution and per-user scoping |
| session_id | cse_... | Ties every cloud API call back to a session transcript |
| session_type | web \| routine \| autofix | Lets policy deny unattended triggers |
session_type matters. An operator will reasonably want to grant a role to interactive web sessions while denying it to Routines and Auto-fix, since those run without a human present. Making that expressible in the IAM condition rather than in Anthropic's product surface is the right layering.
Example resulting trust policy:
{
"Effect": "Allow",
"Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.claude.com" },
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.claude.com:aud": "sts.amazonaws.com",
"oidc.claude.com:repository": "acme/infra",
"oidc.claude.com:session_type": "web"
}
}
}
Surface
A single environment variable pointing at a request URL, mirroring the Actions convention, is enough:
curl -H "Authorization: bearer $CLAUDE_ID_TOKEN_REQUEST_TOKEN" \
"$CLAUDE_ID_TOKEN_REQUEST_URL&audience=sts.amazonaws.com"
That composes with the existing ecosystem without further work: aws-actions/configure-aws-credentials already consumes this shape, as do google-github-actions/auth, azure/login, Pulumi ESC's OIDC provider, and HashiCorp Vault's JWT auth method.
An optional convenience layer — a per-environment "cloud identity" setting that mints the token and writes AWS_WEB_IDENTITY_TOKEN_FILE + AWS_ROLE_ARN at session start — would make the common case zero-config, since the AWS SDK chain picks those up ambiently. But the raw endpoint is the part that matters; the convenience layer can follow.
Suggested scope for a first cut
- AWS only (
AssumeRoleWithWebIdentity), since it's the highest-volume IaC target and requires no Anthropic-side per-provider work beyond the issuer - Opt-in per environment, off by default
- Token TTL ≤ 15 minutes, minted on demand rather than at session start
- Available on paid individual plans, not gated to Team/Enterprise — solo operators are precisely the population that has no CI budget to fall back on
Alternative Solutions
Add a dedicated encrypted secrets store (#32733). Solves a real and adjacent problem — private package registries, third-party API keys — and should ship regardless. But it doesn't address this one. A stored static cloud credential is still a static cloud credential: it grants standing access, needs rotation, and cannot be scoped per-session or per-repo the way an IAM trust policy can. For cloud provider auth specifically, keyless is strictly better than well-protected keys.
Let CI hold the OIDC trust; Claude only opens PRs. This is the correct architecture for deploys and I'd keep using it there. It fails for the diagnostic loop: Claude can't read plan output, can't inspect live cloud state, and can't iterate. Every cycle becomes push → wait for CI → read a comment → guess. It also assumes a CI budget, which for individual subscribers on a Claude plan is a separate paid product; a Pulumi/Terraform preview on every push is not free at any meaningful volume. The docs also warn that Auto-fix can trigger comment-driven automation like Atlantis, which pushes users toward disabling Claude's involvement on infra repos entirely rather than integrating it.
Run the CLI on a VM with an instance profile and drive it via Remote Control. Works today and is what I'll do in the interim. But it reintroduces exactly the always-on machine that cloud sessions exist to eliminate, and the whole appeal of the web + mobile workflow is having no host to maintain.
Proxy-side credential injection, like the existing GitHub proxy. Anthropic already runs a proxy that substitutes real GitHub credentials on outbound requests, keeping them out of the sandbox — an elegant pattern. Extending it to sign SigV4 requests would be far more invasive than issuing a JWT: it means Anthropic holding customer cloud credentials, implementing per-provider request signing, and becoming a blast-radius concentration point. OIDC keeps the credential material entirely on the customer's side.
Interactive device-code flow (aws sso login) forwarded to the browser or mobile app. Closer to my current local habit, but it authenticates me rather than the session, which is the wrong identity to bind a policy to. It also can't work for Routines, and it requires a human at every session start — losing the asynchronous property that makes cloud sessions worth using.
Priority
High - Significant impact on productivity
Feature Category
Other
Use Case Example
_No response_
Additional Context
Prior art for the exact mechanism being requested:
- GitHub Actions OIDC[^gha] — the closest analogue, and the one every cloud provider's documentation is already written against
- GitLab CI
id_tokens[^gitlab] and CircleCI OIDC[^circle] — same pattern, confirming it's the industry-standard answer for hosted execution environments - AWS
AssumeRoleWithWebIdentity[^aws], GCP Workload Identity Federation[^gcp], Azure workload identity federation[^azure] — all three major providers accept a third-party OIDC issuer with no per-issuer engineering on their side
Because the providers already do the verification work, the Anthropic-side scope is bounded: an issuer, a JWKS endpoint, a discovery document, a token minting endpoint reachable from the sandbox, and the environment config to enable it per environment.
Related: #32733 (secrets store — complementary, not a substitute).
This request is co-authored with Opus 5.
[^gha]: GitHub Actions, "About security hardening with OpenID Connect" — https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect
[^gitlab]: GitLab, "Connect to cloud services" — https://docs.gitlab.com/ee/ci/cloud_services/
[^circle]: CircleCI, "Using OpenID Connect tokens" — https://circleci.com/docs/openid-connect-tokens/
[^aws]: AWS STS, AssumeRoleWithWebIdentity — https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html
[^gcp]: Google Cloud, "Workload Identity Federation" — https://cloud.google.com/iam/docs/workload-identity-federation
[^azure]: Microsoft Entra, "Workload identity federation" — https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation