Skip to content

docs(network): 'Loopback… always blocked' overstates enforcement — native v4 loopback→loopback traffic is allowed; the block is flow-family-specific #3737

Closed

Description

@dlynch90

Summary

The Network Rules doc states: "Loopback, link-local, and unspecified addresses, including the cloud metadata address 169.254.169.254, are always blocked."

Observed on 0.1.1 (local Docker driver, macOS): a workload process connecting to 127.0.0.1:8081 where a native AF_INET listener is bound to 127.0.0.1 succeeds with HTTP 200. Loopback-to-loopback traffic is allowed in practice. What is actually blocked is the v4-mapped flow class — an AF_INET connect to a dual-stack [::] listener — which is reset with no OCSF event (filed separately: #3735).

Reproduction (0.1.1, local Docker driver)

# inside the sandbox:
python3 -m http.server 8081 --bind 127.0.0.1 &   # native AF_INET listener
python3 -c "import urllib.request; print(urllib.request.urlopen('http://127.0.0.1:8081/', timeout=4).status)"
# -> 200  (doc says loopback destinations are always blocked)

Request

Align the docs with actual enforcement: state which traffic is denied (v4-mapped flows to dual-stack listeners) vs which is allowed (native AF_INET loopback→loopback), or align enforcement with the doc. As written, the 'always blocked' claim sends users debugging in the wrong direction — we initially attributed the silent resets in #3735 to a loopback destination block.

Activity

  1. drew commented on Sep 26, 2026

    @drew
    Collaborator

    📋 triage-agent

    Triage Assessment

    Classification: validated-bug (documentation clarity)

    Summary

    The unqualified “always blocked” wording is misleading. In this section, it describes destinations authorized through network policy and allowed_ips; sandbox-local loopback connections are intentionally allowed. The report's native IPv4 loopback result is consistent with the current code and with the sandbox service documentation.

    Investigation

    • docs/how-it-works/policies/network-rules.mdx and schema.mdx both use “always blocked” in the network-policy destination context. crates/openshell-core/src/net.rs defines that restriction for policy endpoints.
    • crates/openshell-sandbox/src/network_broker.rs handles a loopback destination as a local connection before the external TCP policy path. docs/how-it-works/sandboxes/overview.mdx instructs users to bind exposed services to 127.0.0.1.
    • The wording and code are present in v0.1.1, the reported release. I did not rerun the macOS/Docker reproduction; source evidence supports the reported native IPv4 outcome.
    • bug(network): v4-mapped loopback flows (AF_INET connect to dual-stack listener) get no OCSF DENY event — silent RST or hold-then-timeout #3735 is related but distinct. Its reported dual-stack reset and missing OCSF event need separate investigation. This assessment does not establish that IPv4-mapped flows are intentionally denied.

    Impact Signals

    Human Decision Required

    Decide whether to address the documentation mismatch. If accepted, clarify that the always-blocked ranges apply to policy-authorized outbound destinations, while sandbox-local loopback services remain reachable. Keep enforcement and OCSF decisions for #3735 separate. Record acceptance with state:accepted, roadmap placement, or both; otherwise close as not planned with a rationale.

  2. added this to the OpenShell 0.1.2 milestone on Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions