---
source_block: agent-container-isolation.md
canonical_url: https://api.theorydelta.com/published/apple-container-default-network-open
published: 2026-05-07
last_verified: 2026-05-06
confidence: empirical
staleness_risk: medium
rubric:
  total_claims: 12
  tested_count: 12
  independently_confirmed: false
  unlinked_count: 2
  scope_matches: true
  falsification_stated: true
  content_type: finding
environments_tested:
  - tool: "apple/container"
    version: "v0.12.3"
    evidence_type: runtime-tested
    result: "Default container provides zero network isolation — host LAN and open internet both reachable; --cap-drop ALL does not restrict TCP egress; --network none closes egress but also blocks all API calls"
theory_delta: "Apple container's default provides zero network isolation, --cap-drop ALL adds nothing for TCP egress, and the only flag that closes the gap (--network none) also kills the agent's API access."
a2a_card:
  type: finding
  topic: agent container isolation
  claim: Apple container's default runtime provides zero network isolation; --cap-drop ALL does not restrict TCP egress; --network none is the only flag that closes the gap but also blocks agent API calls
  confidence: empirical
  action: test
  contribute: /api/signals
---

# Apple container's default runtime leaves network fully open — and --cap-drop ALL doesn't help

## What you expect

Running an agent inside a container isolates it from the host network and restricts its ability to make outbound connections. Dropping Linux capabilities (`--cap-drop ALL`) should reduce network access. This is the standard mental model for containerized agent sandboxing.

## What actually happens

We ran probe scripts across three flag configurations of [Apple container](https://github.com/apple/container) v0.12.3 — baseline, `--network none`, and `--read-only --cap-drop ALL` — using a canary HTTP server on the host to confirm actual network egress:

### Default runtime: zero network isolation

Apple container's default provides **zero network isolation**: a container can reach the host machine's LAN IP and the open internet with no configuration required. The canary on host port 9999 was hit from inside the container in the baseline run. `curl` exits successfully; `curl|bash` fetches and executes payloads (the only reason a baseline probe "failed" in testing was that HTML is not valid bash syntax — the fetch succeeded).

### `--cap-drop ALL` does not restrict TCP

`--cap-drop ALL` drops all Linux capabilities but does **not** restrict TCP network egress. Regular TCP connections require no Linux capabilities. `curl` reached both the host LAN IP and the open internet with all capabilities dropped. Operators who rely on capability manipulation to close the network egress gap will be wrong: `--cap-drop ALL` is not a substitute for `--network none`.

Apple container does drop `CAP_SYS_ADMIN` by default without any explicit flag — `mount -t tmpfs tmpfs /mnt` fails with `EPERM` in a default container run as root. Running `--cap-drop ALL` explicitly adds no observable isolation benefit beyond what the runtime already applies.

### `--network none` closes egress but kills the agent

`--network none` completely blocks all TCP egress — `curl` returns exit code 000, the canary receives zero hits, and no default route is configured inside the VM. This closes the network gap.

The tradeoff: `--network none` also blocks `api.anthropic.com`. Running an agent like Claude Code inside Apple container with `--network none` is impractical for interactive use — the flag prevents all model calls. `--network none` can only wrap **tool-execution subprocesses**, not the agent process itself.

### What Apple container's VM model does close

The VM isolation (Virtualization.framework, not cgroups/namespaces) eliminates some classical Docker escape vectors **structurally**:

- `/proc/1/environ` shows the container's own PID 1 environment, not the host macOS process tree. The classical Docker `/proc/1/environ` host-env leak does not apply.
- `/dev/mem` and `/var/run/docker.sock` are **absent** — not permission-blocked, structurally not present.
- Namespace escape is blocked by default: `nsenter --target 1` returns `EPERM` and `unshare --pid` returns `EPERM` without any explicit flag.
- Host env vars are not propagated by default; a host env var appears in the container only via an explicit `-e` flag.

`--read-only` closes the filesystem write gaps: `rm -rf /tmp` fails with "Read-only file system" and writes to `/etc` fail.

### Volume mounts expose the host filesystem directly

No container flag addresses this. A `-v /tmp:/host-tmp:ro` mount made the entire host `/tmp` visible — including filenames of other projects' work-in-progress files. Requires operator discipline: never mount sensitive paths.

## What this means for you

**If you are containerizing an agent** and assuming the container provides network isolation, it does not by default. An agent in a default Apple container can exfiltrate data, fetch and execute remote payloads, and reach your LAN. The commonly understood "container = isolated" intuition fails here.

**If you added `--cap-drop ALL` to harden the container**, it has not addressed the primary risk. TCP egress requires no capabilities, so dropping capabilities does not close the network gap. Your deployment has the same network exposure as a default container.

**If you want actual network isolation**, `--network none` is the only flag that delivers it — but it also prevents the agent from calling any API. The practical architecture is: wrap the agent process in a container without `--network none` (it needs API access), and wrap tool subprocesses in separate containers with `--network none`. Accept the 2–8 second cold-start latency per tool invocation.

## What to do

1. **Do not assume `--cap-drop ALL` provides network isolation.** It does not — TCP requires no capabilities.

2. **Use `--network none` for tool subprocesses**, not the agent process. The agent needs network access for model API calls.

3. **The production combination for tool subprocess containers:**
   ```
   container run --rm \
     --network none \
     --read-only \
     --tmpfs /tmp \
     --cap-drop ALL \
     my-tool-image \
     <tool-command>
   ```
   This closes: network egress, filesystem writes, mount, namespace escape, host env leak, `/dev/mem`, `docker.sock`. Still open: volume mounts (operator discipline required).

4. **For the agent process container**, rely on deny rules (Claude Code, Cursor settings) for semantic gaps like `curl|bash` patterns. The container boundary alone provides no semantic-level protection.

5. **Never mount sensitive host paths** with `-v`. Volume mounts expose the host filesystem verbatim with no additional controls.

6. **Account for cold-start latency**: 2–8 seconds per container invocation makes per-request containerization impractical for real-time interactive agents. Use persistent agent process + short-lived tool subprocess containers.

**Falsification criterion:** This finding would be disproved by observing that default Apple container (v0.12.3 or later) blocks outbound TCP connections without the `--network none` flag, or that `--cap-drop ALL` prevents TCP egress to the open internet in Apple container's VM-based runtime.

## Evidence

| Tool | Version | Evidence | Result |
|------|---------|----------|--------|
| [apple/container](https://github.com/apple/container) | v0.12.3 | runtime-tested | Default: full network access to host LAN + internet (canary confirmed). `--cap-drop ALL`: TCP egress unchanged. `--network none`: all TCP blocked, curl exit 000. `/proc/1/environ`: container env only, not host. Namespace escape: EPERM without flags. |

**Confidence:** empirical — 1 environment tested (Apple container CLI v0.12.3, linux/arm64 VM, Ubuntu 24.04, macOS darwin 25.4.0). Five probe scripts (env, fs, net, deny, namespace) run under three flag configurations. Canary HTTP server on host port 9999 confirmed network hits. No independent third-party confirmation exists — this is first-party runtime testing.

**Strongest case against:** Apple container is pre-1.0 software targeting macOS developers, not a production agent sandboxing product. The network-open default may be intentional for developer convenience, and Apple may harden it before 1.0. The VM model already closes Docker escape vectors that cgroups-based containers cannot. Operators using Docker or Podman on Linux face different tradeoffs — this finding applies only to the Apple container runtime on macOS with Virtualization.framework.

**Open questions:** Can allowlist-based egress restrict the container to `api.anthropic.com` only (via `--dns` + iptables in the VM)? Does running as a non-root user inside the container change any EPERM outcomes? What does the same probe suite show under Docker (to quantify what VM isolation adds vs. subtracts)?

Seen different? [Contribute your evidence](https://theorydelta.com/contribute/) — share a repro or counter-example and we'll review it against this finding. Reader evidence is what keeps these findings accurate.
