nftables

nftables provides per-agent network isolation by installing packet filter rules at spawn time. The rules enforce the agent's spec.network policy.

Network Policies

PolicyBehavior
noneAll network access denied. The agent cannot make or receive network connections.
localOnly loopback (127.0.0.1/::1) and local network connections allowed.
allowlistOnly connections to hosts in spec.network.allowlist are allowed.
fullUnrestricted network access.

Manifest Configuration

spec:
  network:
    policy: allowlist
    allowlist:
      - "api.openai.com:443"
      - "api.example.com:443"
      - "*.internal.company.com:8080"

How Rules Are Applied

At spawn time, agentd creates nftables rules in a per-agent table. The rules are applied to the agent's network namespace (created during spawn).

For allowlist policy, rules permit TCP connections to listed hosts only. All other outbound connections are dropped.

table inet scarab-agent-<uuid> {
    chain output {
        type filter hook output priority 0; policy drop;
        ip daddr 1.2.3.4 tcp dport 443 accept;
        ip6 daddr ::1 accept;
        # deny all else
    }
}

Allowlist Format

Each allowlist entry is <host>:<port>:

  • api.openai.com:443 - specific host and port
  • *.example.com:443 - glob matching subdomains (resolved to IPs at spawn time)
  • 192.168.1.0/24:80 - CIDR range

DNS Resolution

Hostnames in the allowlist are resolved to IP addresses at spawn time. If the IP changes after spawn, the agent will be blocked. For dynamic IPs, use CIDR ranges or the full policy with application-level filtering.

Interaction with seccomp

For none network policy, seccomp also blocks the socket() syscall to provide defense in depth. Both layers enforce the restriction independently.

Validation

sudo cargo test nftables

Tests create an agent with none network policy and verify it cannot reach external addresses.