Network Egress Policy
Status: Partially implemented — Docker grant-based allowlists, launch-contract enforcement-quality reporting, fail-closed Capsule guest firewall for the role container, and DinD-inner residual-risk coverage are documented and tested; inner-container enforcement parity, rule editing, connection decision logs, service-port policy, and non-Docker backend parity remain open (Containment track, Agent Orchestration Program)
Shipped facts
DockerGrants carries a NetworkGrant tri-state (none / allowlist / open) plus an allowed_hosts: Vec<String> allowlist, resolved per Docker security profile (crates/jackin-core/src/docker_security.rs). Launch renders a session contract that prints both the requested network mode and an honest enforcement-quality label — full, partial (sudo grants iptables access), partial (DinD inner containers bypass host iptables), or n/a — via network_enforcement_label (crates/jackin-runtime/src/runtime/docker_profile.rs), surfaced under --debug and exported as JACKIN_NETWORK_MODE/JACKIN_NETWORK_ENFORCEMENT container env (crates/jackin-runtime/src/runtime/launch.rs).
Plan 052 covers the DinD-inner case as an asserted residual risk: when allowlist networking and DinD are both active, the debug session contract reports partial (DinD inner containers bypass host iptables) and the role container receives the same enforcement label through JACKIN_NETWORK_ENFORCEMENT. The repeatable coverage is the focused session_contract_reports_dind_inner_egress_partial_enforcement runtime test; host-level packet proof remains out of the default local/CI gate because it requires privileged networking setup beyond the role-container firewall path.
The firewall-apply Capsule subcommand installs a fail-closed iptables OUTPUT allowlist from JACKIN_ALLOWED_HOSTS (domains resolved via getaddrinfo, IPv4 CIDRs/literals allowlisted through an ipset) plus an ip6tables deny-all fallback, run host-side via docker exec before the agent session starts (crates/jackin-capsule/src/firewall.rs). The default-DROP policy and loopback/established accepts install before DNS/allowlist rules, so a mid-apply failure leaves egress closed rather than open. This firewall only applies inside the role container.
Remaining work
- DinD guest enforcement parity. The firewall is only applied to the role container; the DinD sidecar and any agent-created inner containers have no enforcement coverage today. That bypass is now named and asserted as partial enforcement, but enforcing inside the inner Docker daemon needs a separate proxy-sidecar or inner-Docker firewall design.
- Connection decision logs. No per-connection audit trail exists (timestamp, instance, destination host/IP, port, protocol, rule matched, allow/deny, enforcement backend).
- Rule editing surface.
allowed_hostscan only be set by hand-editingconfig.toml/jackin.role.toml; there is no CLI orjackin consoleflow to add/inspect/remove allowlist entries before launch. - Service-port policy. Published container ports, sandbox-to-host aliases, local dev-server/database access, and model-runner endpoints are not modeled as part of network policy.
- Non-Docker backend parity. No egress enforcement exists yet for OrbStack, smolvm, Kubernetes, or SSH-remote backends; a host-side proxy design for microVM-style backends and a Kubernetes/remote policy mapping remain unstarted. See Network egress policy design for the backend strategy and external references behind this.
Related work
- Selectable sandbox backends — Docker Sandboxes and microVM comparison this item's backend parity depends on
- Docker runtime hardening contract — sibling Docker profile/grant hardening work
- Session contract and explain mode — the operator-visible contract surface this item feeds
- Host bridge — candidate home for a future host-side egress proxy
- Network egress policy design — design rationale, enforcement-quality vocabulary, and source materials