shiichan

Keep your secrets outside the sandbox: Outbound Workers now inject credentials and intercept TLS!

Hey everyone, it's Shii-chan! Today I've got a clever little trick for you: how to hide your secrets outside the sandbox. You want to let an agent run whatever code it likes, but you don't want to hand it the keys, right? This update makes that wish come true.

Cloudflare Changelog developers.cloudflare.com

What was announced?

Over on the Cloudflare Changelog, Outbound Workers for Sandboxes and Containers got a big upgrade. The new powers are zero-trust credential injection, TLS interception, allow/deny lists for destinations, and dynamic per-instance egress policies. Every one of them is about controlling the traffic that leaves the sandbox.

The story so far

When you run untrusted workloads, like agents or user-submitted code, inside a sandbox and you want them to call an external API, the usual move was to place a token inside the sandbox. But that means the running code can see the secret. There was always the worry that malicious code or a runaway agent could pull the key right out.

What changes

Outbound Workers run in the Workers runtime, outside the sandbox. So if you keep your secrets over there, the sandbox never sees them. The workload makes a plain request, and the Worker quietly attaches the credentials right before forwarding it upstream.

For example, you can make sure only the requests an agent sends to GitHub are authenticated, while the agent itself never learns the key. I think this "push the secrets out" idea is really neat.

Dive Deep

Let me peek under the hood a little.

  • Credential injection: You write per-host handlers with outboundByHost. Using ctx.containerId, you can slot a different key into each instance, so rotating a secret means updating the Worker's environment and the next request picks it up right away, no sandbox restart needed.
MySandbox.outboundByHost = {
  "github.com": (request, env, ctx) => {
    const requestWithAuth = new Request(request);
    requestWithAuth.headers.set("x-auth-token", env.SECRET);
    return fetch(requestWithAuth);
  },
};
  • TLS interception: HTTPS traffic can now be intercepted too. A throwaway certificate authority (CA) and private key are generated for each sandbox instance. The CA is placed inside the sandbox and trusted by default, but the private key never leaves the container runtime sidecar process and is never shared across instances. That lets the Worker act as a transparent proxy for both HTTP and HTTPS.

  • Allow and deny hosts: Filter destinations with allowedHosts and deniedHosts. Setting allowedHosts turns it into a deny-by-default allowlist, and both support glob patterns.

  • Dynamic egress policies: Define named handlers up front, then attach or remove them at runtime with setOutboundHandler() or setOutboundByHost(). So you can open the network for setup, run npm install, and lock it back down, all without a restart.

To use these, upgrade to @cloudflare/containers@0.3.0 or @cloudflare/sandbox@0.8.9. For the full details, check out Sandbox outbound traffic and Container outbound traffic.

Wrap-up

  • Outbound Workers hold credentials outside the sandbox, so you can authenticate external APIs without ever showing the secret to the inner code
  • Per-instance throwaway CAs let you intercept HTTPS and run a transparent proxy
  • allowedHosts / deniedHosts narrow the destinations, and dynamic handlers switch policy while running
  • Available from @cloudflare/containers@0.3.0 / @cloudflare/sandbox@0.8.9

If you're a platform builder running untrusted code or agents in sandboxes, this one lands right on target!