Repository navigation
Kubernetes boundary mode matches policy binary symlinks literally, without any log #4834
Description
User Story
I run OpenShell 0.1.4 on Kubernetes as the sandbox backend for OpenClaw Enterprise dedicated Codex agents. A network rule for the agent's node binary stopped matching when the agent image provided that binary through a symlink, and nothing in the logs said why.
Problem Statement
In the Kubernetes isolation-boundary topology, the supervisor never resolves symlinks in policy binary paths, and it skips that step without logging. crates/openshell-supervisor/src/lib.rs passes process_enabled = false to run_networking (v0.1.5 lines 1106-1110), and the supervisor's entrypoint_pid (line 990) is never set. run.rs then takes the "No process supervisor" branch (line 357) silently, and later policy reloads pass pid 0, which resolve_binary_in_container treats as literal (opa.rs:2097). The sandbox reports the kernel-resolved executable, so a rule that lists a symlink path never matches.
The local process mode resolves the same rule and logs the result, or warns when it cannot. The code is the same on v0.1.4, v0.1.5 and main (39d95b4).
Impact / Why This Matters
The Binary Matching section of docs/how-it-works/policies/network-rules.mdx does say to list real paths, so this is within the contract. But the same policy behaves differently between the local and Kubernetes topologies, and the only signal is a transparent_tcp_policy_denied event naming a path that is not in the policy. In our case a workspace-node connection was denied indefinitely, and it took reading the supervisor source to find out why. Workaround: list the real path (readlink -f inside the sandbox). Downstream report: openclaw/openclaw-enterprise#3216.
Acceptance Criteria
- In boundary mode, either a rule that lists a symlinked binary matches the process running its target (same as the local mode), or the supervisor logs one warning at startup that policy binary paths are matched literally.
- The Binary Matching docs state how boundary mode handles symlinked paths.
Reproduction Steps
- Run the gateway with the Kubernetes compute driver, so the supervisor runs in its own Pod.
- Create a sandbox from an image where
/usr/local/bin/nodeis a symlink to/usr/bin/node-24, with a network rule whosebinarieslists/usr/local/bin/nodeand whose endpoint allows<host>:443. - From the sandbox, have
nodeconnect to<host>:443. - The connection is denied with the identity
/usr/bin/node-24, and the supervisor log has no symlink-resolution lines.
We hit this with sandboxes created through the gateway API by OpenClaw Enterprise, not with the CLI; the policy shape is the same.
Suggested UX
No configuration change needed. One option for the fix: the sandbox side already resolves process identities, so it could resolve policy binary paths too and send the aliases across the boundary.
Environment
OpenShell gateway, supervisor and sandbox 0.1.4 (the 0.1.4 tags of ghcr.io/nvidia/openshell/{gateway,supervisor,sandbox}), Kubernetes 1.35, amd64. Source checked against v0.1.4, v0.1.5 and main 39d95b4.
Logs
INFO openshell_supervisor: Isolation boundary attached
INFO openshell_supervisor: Isolation boundary enforcement confirmed
OCSF NET:OPEN [MED] DENIED /usr/bin/node-24(0) -> <host>:443 [reason:transparent_tcp_policy_denied]
None of "Policy binary symlink resolution complete", "Entrypoint PID never published" or "Container filesystem ... not accessible" appears in the supervisor log.
Activity
EmilienM commentedon Oct 22, 2026
This is a won't fix for now, we'll add a symlink in our images.