Phase 03 · Network containment

Network containment

Deny-by-default network authority where destinations are classified from their bytes, hostnames are not invented from reverse DNS, and unknown stays unknown.

Permanent ruleNo matching allow rule → deny. A contained process does not inherit your network.

An agent allowed to reach one API endpoint has not been allowed to reach your router, your NAS, your local Postgres, or the printer. Network containment treats those as different authority, because they are.

Endpoint identity

NetworkEndpointIdentity keeps these apart rather than collapsing them into one “destination” field:

  • the requested hostname, as supplied
  • the normalised hostname
  • the resolved address, if a trusted platform source resolved it
  • the observed address, if a flow was actually seen
  • port, address family, network category
  • interface identity and local service name where available
  • the hostname evidence source and resolution state

A hostname rule can match only hostname evidence that came from a trusted platform source or explicit development input. BitShout does not create hostname identity from a reverse DNS lookup, because reverse DNS is controlled by whoever owns the address.

Classification is byte-level

Address category is decided from the bytes, not from the text:

Category Ranges
loopback IPv4 127.0.0.0/8, IPv6 ::1/128, IPv4-mapped IPv6 loopback
local network IPv4 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16; IPv6 fc00::/7
multicast including mDNS/Bonjour discovery traffic
internet everything routable that is none of the above
unknown insufficient evidence to classify

127.0.0.1 is loopback because of what it is. The string localhost, with no resolved or observed address behind it, is hostname-only evidence and stays category unknown — and for a contained subject, unknown is denied. That row is the one worth remembering: it is the difference between classifying a destination and reading a label off it.

The request model

NetworkAccessRequest records the flow identifier where available, direction (outbound, inbound, unknown), protocol (tcp, udp, icmp, other, unknown), local endpoint where available, remote endpoint, flow type, and the Phase 1 subject and session identity with its source-attribution evidence.

The evaluation that comes back records the request, the containment resolution, the structured policy decision, observation state, enforcement state, the native event name, and a timestamp — with the decision time in microseconds, because a boundary that is too slow to sit in a network path is not a boundary you can deploy.

Separate authority, separately granted

Each of these is its own grant, and none implies another:

  • outbound connections to a specific host and port
  • LAN destinations
  • loopback services
  • multicast and Bonjour/mDNS discovery
  • inbound listening

A protected process that legitimately needs api.anthropic.com:443 has, on that basis, no authority to open 192.168.1.40:22.

Enforcement boundary

Network verdicts are designed for a NEFilterDataProvider Network Extension path. The restricted Network Extension entitlement is approved by Apple; packaging, installation and the user’s own approval on the machine are what remain between a policy decision and an operating-system denial. Where that chain is not complete on a given Mac, the verdict is labelled “Observed — Policy Would Deny” rather than “Blocked” — the label always reports what actually happened, never what was configured.