Egress control · agent containers
Put Claude Code or Codex
in a default-deny box.
Outcall gives new users a one-command run path: install once, let the Linux installer preload the matching daemon image, run outcall to scaffold one project, auto-detect Claude Code or Codex when the host makes that unambiguous, copy only the auth/config you intend, verify the isolated container path, and launch the real agent directly. Network policy is enforced by nftables, DNS, and an HTTP proxy the container cannot bypass. If you want the explicit subcommand, use outcall start. If the host matches both providers, fall back to outcall run claude or outcall run codex. Every allow you write becomes an nft list table counter you can read.
curl -fsSL https://outcall.dev/install.sh | sh
# /etc/outcall/rules.d/agent.yaml
# Default-block is implicit. Write only what the agent may do.
# HTTPS is matched by hostname (SNI). Method/path are visible
# only for plaintext HTTP — no TLS interception.
version: "1"
rules:
- id: allow-openai
description: "agent may call the OpenAI API over HTTPS"
condition: 'http.host == "api.openai.com"'
action: allow
egress:
mode: proxy
- id: allow-github-clone
condition: |
dns.query == "github.com" ||
http.host == "github.com"
action: allowWhat's in the box
One daemon. Six surfaces. Same source of truth.
Outcall ships the network plumbing, the policy plane, and the operator UX as a single binary. You don't stand up six tools to enforce egress — you stand up one.
Each agent host gets one Linux bridge with `policy drop` on FORWARD. Allow rules you write compile to nftables verdicts and hit-counters. Verify any rule is live with `nft list table inet outcall`.
The bridge gateway answers only for hosts in your rule set. Unlisted lookups return NXDOMAIN — agents fail immediately at name resolution, not after a 30-second TCP timeout that taints retries.
A forward proxy on the bridge matches plaintext HTTP on host + method + path, and HTTPS on CONNECT host + TLS SNI — no decryption, by design. A per-rule intercept mode is specified (S011) but intentionally not implemented in v0.1; HTTPS method/path/body is not visible inside the encrypted tunnel.
A Unix socket inside each container lets the agent ask the daemon via `outcall fetch <url>` (or `outcall exec`, `outcall file`, etc.) before acting, and submit new rule requests for operator approval. The agent never touches host policy directly; rule changes are auditable.
Drop YAML into `/etc/outcall/rules.d` and `outcall rules reload`. Networks and containers outlive the daemon — you can ship a rule change in seconds without rolling a single agent.
The `outcall` CLI, the JSON API on `/tmp/outcall/host.sock`, and the web dashboard all read the same daemon state. What you see in the UI is what `outcall rules list` prints — no separate inventory to drift.
How it fits together
One bridge. One source of truth.
The daemon is the only thing on the host that can change policy. Operators talk to the host socket. Containers talk to the agent socket. Neither side reaches the other.
Stop trusting agent defaults.
Start with one isolated project.
Outcall is open source, spec-first, and Linux-native. Install once, run outcall, and let it launch the isolated agent directly when detection is clear. Use outcall start when you want the explicit subcommand. If this host matches both providers, choose explicitly with outcall run claude or outcall run codex.