Give agents API access without putting credentials in the sandbox | Superserve Blog
[ new ]Claude Managed Agents on SuperserveIntroducing Claude Managed Agents on Superserve→<br>392Get started<br>Open menu
Set an API key as an environment variable on a sandbox and any command the agent runs can read it. One cat and the key is exposed. It's the same mistake as committing a .env to git, except now the thing reading it is an agent you pointed at the open internet.
Today we're shipping Secrets . You attach a credential to a sandbox, your code uses it like any normal environment variable, and the real value never enters the sandbox. The code only sees a stand-in token. We swap it for the real credential as the request leaves the sandbox, and only for the hosts you allow.
Why API keys leak out of sandboxes
Passing an API key through an environment variable is the normal way to give code a credential. On your laptop that's fine: you own the keys and you wrote the code. A sandbox is different. It runs code you don't fully trust, on inputs you don't control: a repo, a web page, a support ticket. The moment that code can run commands and read a live credential, one prompt injection turns into a leaked key.
This bites hardest when you run a coding agent like Claude Code or Codex inside the sandbox, but it's just as true when the agent stays on your server and only uses the sandbox to run its tool calls. Either way, the model decides what executes in there.
It doesn't take an exploit. Anything the model can run is enough - a generated shell line, cat .env, or printenv:
bashCopy<br>$ printenv ANTHROPIC_API_KEY<br>sk-ant-api03-rLf9... # the real key, ready to be sent anywhere
It's not even a hack. People just ask agents to drop their .env, and they do:
Harnesses like Claude Managed Agents avoid this by design: the agent loop runs outside the sandbox, so no credentials ever need to go in. But as more teams run agents directly inside the sandbox (Claude Code, Codex, custom loops that need to hit APIs mid-task), that protection disappears. Secrets is built for exactly that case.
The missing layer
The requirements sound simple: no key in the sandbox, the agent can't exfiltrate it, and streaming input and output still work. Until now, meeting them meant building and running a credential-substituting layer yourself. So most teams avoided the work and set the env var hoping nothing read it. Some teams, like Listen Labs, actually took the plunge and built it. Secrets is that layer, now available natively with Superserve sandboxes.
How it works
Store the credential once. The value is encrypted at rest and write-only. You can't read it back out:
typescriptCopy<br>import { Secret } from "@superserve/sdk"
await Secret.create({<br>name: "anthropic-prod",<br>value: process.env.ANTHROPIC_API_KEY,<br>provider: "anthropic",<br>})
Bind it to a sandbox by the environment variable your code already reads. It's a map of environment variable to secret name:
typescriptCopy<br>import { Sandbox } from "@superserve/sdk"
const sandbox = await Sandbox.create({<br>name: "research-agent",<br>secrets: { ANTHROPIC_API_KEY: "anthropic-prod" },<br>})
You can also attach or detach a secret on a sandbox that's already running - without having to rebuild.
Inside the sandbox, ANTHROPIC_API_KEY is set like any other variable, so every SDK, CLI, and script that reads it keeps working. The value is a stand-in token shaped like a real Anthropic key, so even clients that check the key's format are happy, but it isn't your credential:
bashCopy<br>$ printenv ANTHROPIC_API_KEY<br>sk-ant-api03-3Qk8... # a stand-in shaped like the real thing, not your credential
When the code makes a request, we swap the stand-in for your real credential as the request leaves the sandbox, on its way to api.anthropic.com. Anthropic sees the real key. The sandbox never holds it. The real value never touches the sandbox's disk, its environment, or /proc. So whatever a compromised agent prints, dumps, or leaks is the stand-in, and it only works on that secret's approved hosts.
Built-in support for the providers you already use
Secrets ships with one-step shortcuts for the services agents actually call. Pick a provider, paste the key, and we set the auth scheme and allowed hosts for you.
That covers the model APIs (OpenAI, Anthropic, Google Gemini, xAI, Perplexity, OpenRouter), developer tools (GitHub, GitLab, Vercel, Cloudflare, Sentry), search (Exa, Firecrawl), and the usual SaaS suspects (Slack, Linear, Notion, Asana, Stripe, Resend). The catalog keeps growing. Want one that isn't here yet? Reach out and we'll add it.
Anything not on the list works too. Create a custom secret with your own header or auth scheme and its allowed hosts, and it behaves exactly the same: the real value stays out of the sandbox.
Scope secrets to exactly the hosts they should reach
A stand-in is only useful on the hosts a secret allows, and you can pair it with network rules so the sandbox can't reach anything else in the...