Back to blog posts

13 min

How to keep API credentials out of AI agent sandboxes

Learn how an egress proxy keeps API credentials out of AI agent sandboxes, reduces blast radius, and enables centralized audit logging without restarts.

Nicolas LecomteNico is a founder of Blaxel, who usually writes about AI, agentics, and the future of AI runtimes.

Your agent needs to call Stripe and Salesforce. It also needs to call an internal data API. Each service wants a credential. The default move passes credentials into the sandbox as environment variables. The agent reads them at runtime and attaches them to outbound requests. The task completes. That agent now holds production credentials inside an environment running code your team never reviewed. The same agent may install a dependency mid-task while a live Stripe credential sits in its environment.

Prompt injection or untrusted code can read those variables. That includes poisoned dependencies and code generation errors. The credentials can then be sent to an attacker. Sandbox isolation protects the host from the workload. It leaves credentials inside the sandbox fully readable. The fix is architectural: move credentials into an egress proxy on the network path.

The proxy attaches the right credential to each authorized outbound request. It also gives you one place to log every call. Credential custody stays outside agent execution.

TL;DR

  • Environment variables are the wrong model for untrusted code: A sandboxed process can often read its own initial environment via /proc/self/environ, but access can be limited by procfs permissions, ptrace-style checks, mount options, or sandbox/runtime policies. That includes code the agent generated a second ago.
  • The egress proxy holds the credentials: They live in the proxy's encrypted store. The proxy attaches them to authorized outbound requests for the agent.
  • Agents never touch production credentials: The agent sends an unauthenticated HTTP call. The proxy intercepts it, injects the credential, and forwards it.
  • Compromised code can't leak what it never held: Exposure shrinks to calls the proxy authorizes during that session. It no longer includes every credential in the environment.
  • One interception point for logging: Outbound calls using the configured proxy path cross one point. Log destination, timestamp, and credential identifier, but never the credential value.

Why environment variables fail for agent workloads

Environment variables work for code your team wrote and reviewed. The process that reads them is trusted, and so are the operators. Agent sandboxes break both assumptions. Environment variables are "not recommended unless the other methods are not possible," according to OWASP's Secrets Management Cheat Sheet.

Agents execute untrusted code by design

The code inside an agent sandbox may be model output or user-supplied code. It may also come from third-party tool integrations. Nobody on your team reviewed it. When that code runs with credentials in its environment, it can read them. Credentials in environment variables can leak through diagnostic functions or /proc/self/environ. OWASP's Cryptographic Storage Cheat Sheet warns about both paths.

Supply chain malware already hunts for exactly this. In June 2026, IronWorm malware hit 36 npm packages. It scanned 86 environment variables and 20 credential files. That breadth makes any credential exposed inside the sandbox a practical target. The hunt covered OpenAI, AWS, Anthropic, and npm credentials. It also covered vault configs and SSH keys.

A coding agent may run npm install mid-task to add a charting library. That command hands control to a post-install script. The script runs beside the STRIPE_KEY passed in at sandbox creation. Reading it can be as simple as running env. Prompt injection reaches the same credential without any malicious package.

Secrets sprawl across sandbox instances

Teams running coding agents in production spin up large fleets of short-lived sandboxes. Webflow uses Blaxel sandboxes to power real-time previews for its AI coding agent. Each needs the same Stripe key, GitHub token, or warehouse credential. Environment variables copy those credentials into every ephemeral environment.

On Blaxel, the copies are also frozen. The variables documentation states that "Environment variables cannot be added or changed after a sandbox is created." Rotation means recreating every sandbox that holds the old value.

The copy problem appears in how long leaked credentials stay live. Verizon's 2025 Data Breach Investigations Report found a median of 94 days to remediate GitHub-leaked secrets. Some remained exposed past 160 days. That delay can leave every copied sandbox credential usable for months.

For a sandbox fleet, every place holding a credential becomes another place requiring revocation. No central record ties a sandbox to a credential version. An auditor asking where a credential went gets no answer.

How the egress proxy pattern works

An egress proxy is a forward proxy on the sandbox's outbound path. It holds credentials and adds them to requests in flight. Use application-layer filtering to control that outbound path. CIS Controls v8 safeguard 13.10 names filtering proxies, application-layer firewalls, and gateways as examples. Google Cloud's Secure Web Proxy ships a default deny-all setting. It blocks outbound traffic until a rule permits it.

The newer use adds credential injection to the chokepoint's traffic filtering.

The proxy intercepts and enriches outbound requests

Outbound HTTP requests using the configured proxy path enter the proxy before leaving your infrastructure. The proxy matches each destination domain against configured rules. When a rule matches, it adds the credential and forwards the request.

Blaxel's proxy secrets injection implements this per sandbox. Routing rules live under network.proxy.routing as an array of ProxyTarget objects. Each object has four fields: destinations, headers, body, and secrets. Header and body values use {{SECRET:name}} placeholders. The proxy resolves those placeholders server-side.

Secrets are scoped per routing rule. Therefore, a Stripe key never rides along on an OpenAI request. The secrets field is write-only and stripped from API responses. It is also stored encrypted at rest.

From the agent's side, a call to api.stripe.com leaves without an Authorization header. The proxy adds Authorization: Bearer sk_live_... before the request leaves Blaxel's infrastructure. From Stripe's side, a fully authenticated request arrives. Stripe processes it like any other request. Nothing in Stripe's logs distinguishes a proxy-injected header from one set by the caller.

Sandbox processes retain only the request context available before proxy forwarding. The authorized upstream service receives the injected credential, without leaving a STRIPE_KEY in the sandbox environment, a token in a config file, or credential material in sandbox memory.

Compromised code may inspect its pre-proxy headers and search for credentials by enumerating variables or grepping files, but it finds nothing to steal.

How to implement credential isolation with egress proxy routing

These four steps move credentials from sandbox environment variables to the proxy layer. They assume Blaxel Sandboxes created with the proxy enabled. The same architecture works with another programmable egress gateway. It must support destination policies, credential isolation, header or body injection, and request logging.

One: Inventory which external services your agents call

List every external API your agents reach and the credential type each requires. Examples include an API key, OAuth token, bearer token, or mutual TLS certificate. Capture the exact header name each provider expects, such as Authorization for Stripe. That detail becomes the headers key in a routing rule later. An inventory row can then map directly onto a rule.

For each row, record the destination and credential type. Add the expected injection location. Also identify which agent types need access. Do not give every sandbox the union of all service permissions. A coding agent may need GitHub and a package registry. A data agent may instead need a warehouse and an internal API.

Flag services that allow-list caller IPs because they need a static outbound address. Blaxel's dedicated egress gateways are in private preview. They attach fixed IPs to sandboxes in your workspace. Downstream providers can then allow-list those addresses.

Use this inventory as your allow-list. Permitted external systems should be explicitly listed under OWASP Application Security Verification Standard 5.0 requirement V13.2.4. Group the list by agent type. This keeps each agent's reachable services aligned with its actual task.

Two: Move credentials from sandbox environment variables to the proxy's secret store

Remove every API key and token from the envs array in your sandbox creation calls. Then define one routing rule for each destination. In Blaxel, a rule pairs a destinations pattern with the credentials it may use. Example patterns include api.openai.com or *.example.com.

Use exact hostnames when only one service endpoint needs the credential. Reserve wildcard patterns for services whose required subdomains are known. Keep separate rules when two destinations use different credentials. This prevents a credential from being attached merely because two services share a broader domain pattern.

The headers or JSON body fields specify where each credential lands. Use the placement required by the provider's API. Blaxel's create-sandbox schema defines the supported header and body configuration. Keep the placeholder in the routing configuration rather than application code.

Update the credential through updateNetwork. Blaxel's docs say this merges configuration "without requiring a sandbox restart." A sandbox with updated routing uses the new value on its next outbound request. Each update takes effect without recreating the sandbox. You can revoke the old provider value the same day.

Three: Configure domain allow-listing and injection rules

Deny everything you did not list. Traffic should be denied by default and allowed only by exception, as required by NIST SP 800-53 control SC-7(5). In Blaxel, set network.proxy.allowedDomains so only listed domains are reachable.

When allowedDomains and forbiddenDomains are both set, the allow-list takes precedence. Treat domain filtering and routing as separate controls that work together. The allow-list determines which destinations are reachable. The routing rule determines which credential, if any, gets attached.

Require both controls for credential-bearing calls. An approved destination should have a narrowly matched routing rule. A routing rule should also point only to a destination the agent needs. This pairing prevents a broad network permission from becoming a broad credential permission.

Review wildcard entries before deployment. Replace them with exact domains wherever the external service permits. Group rules by agent type rather than sharing one global list. Generated code reaching an unlisted domain deserves a review of the prompt that produced it.

Four: Verify with a credential access test

Test from inside the sandbox before shipping. Run env and read /proc/self/environ. Then grep the filesystem for prefixes like sk_live and AKIA. Every check should return empty.

Also grep the filesystem for .env, .npmrc, and ~/.aws/credentials. Confirm each path is absent. Repeat these checks using the same sandbox template and startup process used in production. That catches credentials introduced by templates, bootstrap scripts, or package configuration.

Next, send an outbound request without setting the provider's authentication header. A 200 from an authenticated Stripe API endpoint, when your code sets no Authorization header, indicates authentication was supplied somewhere else, such as by an HTTP client, SDK, or proxy injecting credentials. Blaxel tags each proxied request with an X-Blaxel-Request-Id header for tracing. Resolved {{SECRET:*}} values are never returned.

Finally, request a domain outside your allow-list and confirm failure. These tests verify credential absence and successful injection. They also verify destination enforcement. Keep all three checks in continuous integration (CI). That prevents a future template change from reintroducing an environment variable.

Security and operational implications

Moving credentials to the proxy changes attacker exposure and where an auditor finds evidence. It also changes the engineering effort required for key rotation. The answers below assume the Blaxel routing setup from the previous section.

Blast radius reduction for compromised sandboxes

The entry point might be prompt injection or executable code from a malicious dependency or generated script. The attacker can still call allow-listed domains through the proxy during that session. Scope those destinations and routing rules to the smallest set required for the agent's task.

The environment variable model gives up every credential at once. The Nx s1ngularity attack in August 2025 harvested 2,349 credentials from 1,079 systems. The malware scanned each host for GitHub tokens, npm keys, SSH keys, and API keys. One post-install script can compromise every credential stored in a sandbox environment.

Against closed destinations, destination allow-lists achieved 0% attack success. Scope each agent type's allow-list tightly. A fully hijacked agent then has nowhere approved to send what it finds.

Credential scoping also limits which upstream services remain callable during a compromise. Separate Stripe, GitHub, and internal API credentials into distinct routing rules. Do not attach multiple unrelated credentials to one broad destination pattern. The remaining exposure is then limited to approved calls available during that session.

Centralized audit trail for compliance

Every credential-bearing request on the proxy path crosses one point. Log those requests there. Capture the event source, timestamp, destination, and user or process identity, as required by NIST SP 800-53 control AU-3.

SOC 2 criteria CC6.7 and CC7.2 cover authorized transmission and anomaly monitoring. ISO 27001 Annex A control A.8.15 requires protected and analyzed activity and security-event logs. Protect the logs from modification. Review them for anomalous destinations and identities, as well as unusual response patterns.

Without the proxy, an auditor must correlate credential use across sandbox instances. Most of those instances no longer exist. With the proxy, one point can capture destination, timestamp, sandbox identity, credential identifier, and response status.

That single point answers queries the fleet could not. Pull every request to api.stripe.com from the last 24 hours. Each row carries the sandbox identity, routing rule name, and response status.

Credential rotation without sandbox coordination

Rotate credentials by updating a sandbox's routing rules instead of recreating it. No restart or redeploy is required. Follow NIST SP 800-57 guidance and set cryptoperiods of three months to two years for symmetric authentication keys. Such a schedule remains manageable when each update is an API call.

Environment variables turn rotation into a fleet operation. Every sandbox configuration needs the new value. Then every sandbox needs recreation. During rollout, some sandboxes use the old credential while others use the new one.

Plan for fast revocation: 24% of organizations need more than 24 hours after detection. On Amazon ECS, environment-variable secrets are injected at container start. A rotated value requires a new task or forced redeploy. Proxy injection has no client-side cache to expire.

Keep the credential identifier and routing rule name in the audit trail so operators can confirm which version served each request. After the proxy update takes effect, revoke the old provider value and verify the next request uses the replacement.

Move credentials to the infrastructure layer

Keeping API credentials out of agent sandboxes removes a primary exposure path for teams running untrusted production code. Every new sandbox otherwise copies credentials into another place an attacker can read. Blaxel, the perpetual sandbox platform, implements the proxy pattern in its networking layer. Secrets are encrypted and write-only. The proxy injects them into headers or JSON bodies. Each secret is scoped to its routing rule. You can update it on a running sandbox without a restart. Domain filtering and proxy routing are independent; each has its own allow-list configuration.

The proxy secrets injection docs contain the full configuration reference. Proxy routing is a networking feature for Blaxel Sandboxes. They execute agent code in microVMs rather than containers. Tenants do not share a kernel.

Start building on Blaxel or talk to the team.

FAQ

What is an egress proxy for AI agent sandboxes?

Use the direction of traffic and the required control to distinguish these components. A reverse proxy fronts inbound traffic to a service. An egress firewall only permits or blocks outbound destinations and never changes request contents. A credential-injecting egress proxy operates on outbound traffic, modifies authorized requests, and combines destination policy with request enrichment at one boundary.

How does proxy secrets injection differ from a secrets manager?

A secrets manager such as Vault, AWS Secrets Manager, or GCP Secret Manager stores and serves credentials. The workload still fetches the value into memory or the filesystem. The difference is delivery: proxy injection presents the credential to the authorized upstream service rather than the sandbox process. Secrets managers remain useful as the system of record. The proxy changes where the credential gets applied.

Does the egress proxy add latency to API calls?

Blaxel has not published a per-request proxy-overhead figure. For comparison, Istio's Envoy sidecar added 0.63–0.88 ms at p90 and p99 under moderate load. Overhead climbs sharply at saturation. That level of overhead is often negligible relative to an external API round trip. Measure the path under your own request volume and payload profile before setting latency budgets.

Can agents still call APIs if the proxy goes down?

Proxy-dependent API calls stop when the proxy is unavailable, so monitor that path as part of the agent's request flow. Keep the failure visible rather than routing around the control: NIST SP 800-53 control SC-7(18) calls this "Fail Secure." Envoy's external authorization filter defaults to rejecting requests when its authorization service is unreachable. This behavior preserves destination and authorization checks during an outage.

Related articles