The Authentication Problem for AI Agents
AI agents — whether powered by LLMs like Claude or custom models — are increasingly used to automate tasks: responding to chat messages, updating Kanban boards, commenting on GitHub issues, and more. But when you run these agents in a sandbox (a microVM for security and isolation), you face a fundamental challenge: how do you authenticate the agent without exposing secrets?
Traditional methods all have drawbacks:
- API tokens injected via environment variables are simple but insecure — a compromised sandbox could exfiltrate the token. You need rotation and expiry, which adds operational overhead.
- Workload identity tokens (OIDC) improve security by attesting the agent's identity, but many services lack first-class OIDC support, forcing you to build custom token-exchange services.
- Custom proxies offer maximum flexibility but are hard to set up — intercepting all egress traffic, writing dynamic rules, and maintaining performance is non-trivial.
Cloudflare's new outbound Workers for Sandboxes and Containers aim to solve this elegantly. They are programmatic egress proxies that run on the same machine as the sandbox, are written in simple JavaScript, and integrate seamlessly with the Workers ecosystem.
Let's dive into how they work and why they matter for AI-assisted development. For context on the broader trend of AI-assisted coding, check out our analysis of Vibe Coding and its pitfalls.
![]()
How Outbound Workers Work: Code Examples
Outbound Workers intercept all HTTP(S) requests leaving the sandbox. You define a handler — a simple JavaScript function — that can log, modify, or block requests. Here's the basic pattern:
class MySandboxedApp extends Sandbox {
static outbound = (req, env, ctx) => {
// Log all outgoing requests
console.log(`Outbound request: ${req.method} ${req.url}`);
// Block non-GET requests
if (req.method !== 'GET') {
return new Response('Not Allowed', { status: 405 });
}
// Proceed with the request
return fetch(req);
};
}
Zero-Trust Credential Injection
The killer feature: inject secrets without the agent ever seeing them. Use outboundByHost to target specific domains:
class OpenCodeInABox extends Sandbox {
static outboundByHost = {
"my-internal-vcs.dev": (request, env, ctx) => {
const headersWithAuth = new Headers(request.headers);
headersWithAuth.set("x-auth-token", env.SECRET);
return fetch(request, { headers: headersWithAuth });
}
};
}
The sandboxed agent never has access to env.SECRET — the proxy adds it on the fly. This is zero-trust: no token is ever granted to the untrusted workload.
You can also make decisions per-container using the container ID:
static outboundByHost = {
"my-internal-vcs.dev": async (request, env, ctx) => {
// KV is encrypted at rest and in transit
const authKey = await env.KEYS.get(ctx.containerId);
const requestWithAuth = new Request(request);
requestWithAuth.headers.set("x-auth-token", authKey);
return fetch(requestWithAuth);
}
};
Dynamic Policy Changes
Outbound Workers can be changed at runtime. For example, allow NPM and GitHub only during dependency installation, then lock down egress:
class MySandboxedApp extends Sandbox {
static outboundHandlers = {
async allowHosts(req, env, { params }) {
const url = new URL(request.url);
const allowed = params.allowedHostnames.includes(url.hostname);
if (allowed) {
return await fetch(newRequest);
} else {
return new Response(null, { status: 403 });
}
},
async noHttp(req) {
return new Response(null, { status: 403 });
}
};
}
async function setUpSandboxes(req, env) {
const sandbox = await env.SANDBOX.getByName(userId);
// Step 1: Allow only GitHub and NPM
await sandbox.setOutboundHandler("allowHosts", {
allowedHostnames: ["github.com", "npmjs.org"]
});
await sandbox.gitClone(userRepoURL);
await sandbox.exec("npm install");
// Step 2: Lock down completely
await sandbox.setOutboundHandler("noHttp");
}
This pattern minimizes the attack surface — open the network only for what's needed, then close it.

Limitations and Considerations
While outbound Workers are powerful, they aren't a silver bullet:
- TLS MITM complexity: To inspect HTTPS request bodies (for logging or modification), you need TLS interception. Cloudflare handles this with ephemeral CAs per sandbox, but it adds overhead and requires proper certificate trust configuration.
- Performance overhead: Although the proxy runs on the same machine, every outbound request now goes through a JavaScript handler. For high-throughput scenarios, benchmark carefully.
- Vendor lock-in: This feature is specific to Cloudflare's platform. If you need portability, consider abstracting the proxy layer.
- Debugging complexity: When requests fail, tracing the issue through the proxy can be harder than debugging a direct call.
Next Steps for Learning
- Hands-on: Try the Cloudflare Sandboxes Getting Started guide to build your first outbound Worker.
- Deep dive: Explore the
@cloudflare/sandboxand@cloudflare/workers-sandboxpackages for advanced features like dynamic handler switching. - Related reading: If you're new to AI-assisted development patterns, our Python 3.15 Alpha 3 preview covers language-level improvements that can simplify agent tooling.

Conclusion
Outbound Workers for Cloudflare Sandboxes offer a pragmatic solution to the authentication challenge in AI agent development. By combining zero-trust principles (no token exposure), flexibility (JavaScript handlers), and deep integration with the Workers ecosystem (KV, R2, Durable Objects), they enable developers to build secure, observable, and dynamically controllable egress for sandboxed workloads.
As AI agents become more autonomous, security patterns like this will become essential. Start experimenting with outbound Workers today — your future agent will thank you.