NodeOps
UK

Egress-locked Managed Agent worker

Run a self-hosted Claude Managed Agent whose tool calls execute inside a sandbox that can reach your private services but cannot exfiltrate to the public internet. Anthropic keeps the agent orchestration; you own the execution boundary — its filesystem, its network, and its logs.

This is the security posture every self-hosted-sandbox integration leads with. The CreateOS piece that makes it enforceable is the per-sandbox egress allowlist: rules are applied in-kernel on the host and cannot be bypassed from inside the sandbox.

Full source: examples/49-egress-locked-agent-worker. For the same worker without the egress lock, see examples 36 and 37 in the Examples index.

Prerequisites

  • Managed Agents beta access on your Anthropic organization.
  • A self-hosted environment and its environment key (prefix sk-ant-oat01-…). The environment key is generated in the Anthropic Console — there is no API for it — and is the only Anthropic credential that enters the sandbox. Your organization key stays on the host.
  • CreateOS credentials (CREATEOS_SANDBOX_BASE_URL, CREATEOS_SANDBOX_API_KEY).

The example's README walks through obtaining each value.

The pattern: provision open, then lock

Ordering is the whole trick. The worker CLI has to be fetched from the public internet, so the sandbox starts with open egress; you lock it down only once everything the sandbox legitimately needs is already inside.

Lock egress after installing the worker and starting your internal service, but before the agent session runs any tool call. Rules apply live, in-kernel, with no restart, so there is no window where the tightened policy is not yet in force.

  1. Create one persistent sandbox with open egress.

  2. Install the ant worker CLI (needs public egress — still open here).

  3. Start an internal-only service on loopback (127.0.0.1) — a stand-in for your private API or database, never exposed to the internet.

  4. Lock egress to a one-host allowlist:

    TypeScript
    1await sandbox.setEgress(["api.anthropic.com"]);

    From here the sandbox can reach only Anthropic (worker traffic) and loopback (the private service). Every other destination is dropped.

  5. Start the worker (ant beta:worker poll) and bind a Managed Agent session to the self-hosted environment.

  6. Run the session. The agent's tool call curls the private service (succeeds) and curls a public host (blocked), writing both results to a file.

  7. Verify from the host by reading the file back and re-reading the enforced allowlist with sandbox.getEgress().

What the proof looks like

TEXT
1── /workspace/report.txt ──
2## private internal service (expect a JSON record):
3{"service":"internal-inventory","sku":"ACME-42","stock":128,"note":"reachable only from inside your environment"}
4## public internet exfil attempt (expect blocked):
5BLOCKED by egress (curl exit 35)
6── enforced egress allowlist ── ["api.anthropic.com"]

The private record came back; the public host was dropped. Note that DNS still resolves under the lock — only the connection is filtered — so a blocked destination fails as a silent connection error (curl exit 35), not a name-resolution error.

Egress rule forms

setEgress takes an array of allowlist rules. There is no denylist token: to block one destination you list every destination you do want.

FormExampleEffect
hostapi.anthropic.comAllow all ports to that host.
host:portgithub.com:443Allow only that port.
*.host*.internal.exampleWildcard subdomain match.
cidr10.0.0.0/8Allow a private range (e.g. an overlay network).

An empty list, null, or ["*"] allows all outbound traffic. See the Egress REST reference for the complete grammar and the GET/PUT endpoints behind getEgress / setEgress.

100,000+ Builders. One Platform.

Get product updates, builder stories, and early access to features that help you ship faster.

NodeOps is the agentic operating system for production AI. CreateOS is its flagship product.