Claude Managed Agents (beta; first-party Claude API and Claude Platform on AWS only) runs Claude in a sandboxed container where it can execute code and call external services. That immediately raises an enterprise question: how does the agent authenticate to your MCP servers, APIs, and tools without the secret ending up somewhere it shouldn't? The tempting shortcut — pasting an API key into the system prompt or a user message — is a documented anti-pattern, because everything in a session's event history persists server-side. Vaults are the designed alternative.
What a vault is
A vault is a workspace-scoped container for credentials, managed via the SDK (client.beta.vaults.credentials.create and related calls under the managed-agents-2026-04-01 beta header). Three credential types cover the common cases:
| Type | Keyed by | Used for |
|---|---|---|
mcp_oauth | mcp_server_url | OAuth-secured MCP servers; tokens auto-refresh |
static_bearer | mcp_server_url | MCP servers taking a fixed bearer token |
environment_variable | secret_name | CLIs, SDKs, and direct API calls from agent code |
Constraints worth knowing before you design around vaults: a maximum of 20 credentials per vault; keys are unique per vault and immutable; secret fields are write-only and never returned by the API; and credentials are not validated until session runtime. One subtlety for MCP: servers expect OAuth bearer tokens, not a service's native REST API key — a Notion integration token, for example, will not work as a vault credential for the Notion MCP server.
Why prompts never see the secret
The security model is the interesting part. Vaulted credentials never enter the sandbox at all. The container — and therefore the model, and any code the model writes — sees only an opaque placeholder. The real secret is injected by Anthropic-side proxies at egress, after the outbound request has left the sandbox. This means that even under prompt injection, code running in the sandbox cannot read or exfiltrate the credential: there is nothing to steal inside the container. For environment_variable credentials you can tighten this further with a per-credential networking.allowed_hosts scope (the secret is only injected for requests to hosts you list) and an optional injection_location controlling whether it is substituted into a header or the request body.
Binding vaults to a session
Vaults attach to sessions through the vault_ids field at session creation. Anthropic matches credentials to MCP servers automatically by URL, so there is no per-tool wiring. On an existing idle session, sessions.update() can change vault_ids, which is how you swap or add credentials mid-engagement without recreating the session. Because validation happens at runtime, an invalid credential does not block session creation — the failure surfaces later as a session.error event, and authentication retries on the next idle-to-running transition. Build your monitoring accordingly.
Rotation and lifecycle
For OAuth credentials, Anthropic auto-refreshes access tokens using the stored refresh token, so routine expiry is handled for you; if a refresh fails, a vault_credential.refresh_failed webhook event can alert your team. Because credential keys are immutable and secrets are write-only, rotation of static secrets is a replace operation in practice. Archiving is permanent for vaults and credentials, as it is for every Managed Agents resource — read-only, no unarchive. A related pattern applies to GitHub access: the fine-grained personal access token on a github_repository resource likewise never enters the container (git traffic goes through an Anthropic-side proxy), and that token can be rotated on a running session.
Where this fits in your secrets strategy
Vaults do not replace your organization's secret manager; they extend it to the last hop. Keep the source of truth in your existing secret store, provision vault credentials from it programmatically, and treat the vault as a deployment target with its own rotation schedule — the same posture described in keeping API keys and credentials out of your code.
Where to go next
Read session lifecycle and turn management for how session.error events surface, and agent webhooks for wiring up vault_credential.refresh_failed alerts.