Repository navigation
feat(docker): enforce pinned Linux egress allowlists - #48
Merged
Merged
Conversation
Add a recording egress controller and a test asserting that the allowlist controller prepares the network before the container starts and cleans up after destroy, verifying the docker argv carries the prepared network, host mappings and dns settings. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
The egress planner now normalizes resolved addresses, collapsing IPv4-mapped IPv6 answers to IPv4 and rejecting IPv6 link-local targets that cannot carry an interface scope, so pinned destinations are safe to install as firewall rules. A new egress_enforcement module consumes the pinned plan, and the docs no longer claim that allowlists are unavailable in DockerSandbox. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a HostExecutionLocation enum and an execution_location method on the Host trait so security-sensitive controllers can require explicit local machine attestation instead of inferring locality from a host's registration name. Local hosts report Local, the SSH host reports Remote, and custom hosts default to Unknown until they can attest otherwise. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a prepared egress network is supplied, the container now joins that network and resolves approved hostnames through static host mappings instead of Docker's embedded resolver, with DNS pointed at loopback so unapproved lookups cannot reach an upstream resolver. The previous network flags are still used when no allowlist network is present. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
The Docker sandbox now accepts an optional egress controller that validates the host and prepares filtering before a workload starts, and a host wrapper rewrites docker invocations so they run through the controller. Allowlist network policies are refused when no controller is installed, since the default sandbox cannot enforce them. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
The failed create attempt was moved into the map at three call sites, which prevented the value from being used afterwards. Cloning it keeps the attempt available for the surrounding error handling. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Extend the live Docker test suite with a focused test that proves egress, allowlist, and default-denied connectivity against a controlled host listener, and add a CI job that runs it with the live Docker opt-in enforced. The new `TINYBOX_REQUIRE_LIVE_DOCKER` gate makes the test fail loudly when the opt-in is missing instead of silently skipping. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Replace redundant closures with direct function references and collapse a nested conditional into a let-chain when checking retained create attempts. Add a clippy allow for the long Sandbox impl, with no change in behaviour. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Replace the parsed string address with an explicit IpAddr::V4 value in the recording egress controller so the test fixture no longer relies on parse and unwrap. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Hostnames with a trailing dot, such as the fully qualified form of a domain, were not matched against the allowlist because normalization kept the dot. Trimming trailing dots makes those names resolve to the same entry as their dotless equivalents. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add tests asserting that LocalHost reports a local execution location and that the Docker ControllerHost forwards host capabilities, rejects unsupported file transfers and forwards, and passes docker commands through to the inner host. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a test that exercises reading and writing workspace files through the local host and verifies that forwarding returns the requested address unchanged. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
The workspace file test now checks the forwarded address through the accessor and verifies the forward is direct, rather than comparing the returned value directly. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the lockfile to pull in tokio 1.53.3 and move the transitive windows-sys dependency from 0.52.0 to 0.61.2. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
The deprecated AsyncFd constructor is kept because the workspace forbids unsafe code, and the owned file moves directly into AsyncFd so its descriptor stays valid for the AsyncFd lifetime. An allow attribute suppresses the resulting warning. Auto-committed-on: cuttlefish Co-authored-by: Medulla <medulla@tinyhumans.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds opt-in Linux Docker allowlist enforcement using resolver-pinned host/IP/port plans. The native controller verifies a local rootful Linux Engine, installs per-box default-drop IPv4/IPv6 firewall chains before container start, pins container name resolution, and cleans owned firewall/network resources during destroy. Unknown, remote, Docker Desktop, and unsupported hosts continue to refuse allowlists.
Adds a hosted Linux connectivity proof for allowed TCP destinations, denied destinations and ports, DNS bypass attempts, IPv6, published ports, and default-Denied policy. Firewall-mutating coverage runs only on the disposable GitHub-hosted runner; it was not run on the shared host.
Updates Tokio to 1.53.3, which fixes inherited advisory RUSTSEC-2026-0386. The one existing AsyncFd use retains an explicit deprecation allowance because the workspace forbids unsafe code and passes an owned file descriptor.
This is a partial TinyBox#27 implementation. macOS and Windows enforcement and remaining backend/platform gaps are still open.
Refs tinyhumansai#27
Part of tinyhumansai/openhuman#7328
Validation
The docker-network-live CI job runs live_network_policy_controls_host_listener_connectivity with live Docker required.