feat(forge-supervisor): Phase 1 MVP - container sandbox supervisor#36
feat(forge-supervisor): Phase 1 MVP - container sandbox supervisor#36TJUEZ wants to merge 2 commits intoinitializ:mainfrom
Conversation
Implement forge-supervisor, a lightweight static binary that runs as PID 1 inside Forge containers to provide kernel-level network egress isolation. Phase 1 MVP includes: - Transparent TCP proxy with SO_ORIGINAL_DST (iptables REDIRECT target) - TLS SNI extraction (peek ClientHello without terminating TLS) - HTTP Host header extraction for plain HTTP - DomainMatcher port from forge-core (deny-all / allowlist / dev-open) - Privilege drop (setuid/setgid + PR_SET_NO_NEW_PRIVS) - Process exec + signal forwarding (PID 1 duties) - Health endpoints (/healthz, /denials) - NDJSON audit logging to stdout - Dockerfile (static binary, scratch base) - Integration tests Closes: initializ#35
|
@TJUEZ — Detailed review of the Phase 1 MVP. The scope coverage is correct (all 13 MVP tasks present), and there's no malicious or exploitable code. However, there are 7 critical functional bugs that will prevent the supervisor from working, plus several security gaps. Coverage AssessmentAll Phase 1 MVP tasks from issue #35 are addressed:
Phases 2-4 of the supervisor (build pipeline, DNS proxy, seccomp, OPA) are correctly out of scope. Critical Functional Bugs (must fix — supervisor is non-functional without these)1. iptables rules missing
|
| Category | Count | Details |
|---|---|---|
| Critical functional bugs | 7 | nat table, priv drop loop, port byte order, consumed bytes, SNI offset, shared buffer, scratch Dockerfile |
| Security concerns | 7 | No setgroups, no cap drop, Setctty, Host offset, hardcoded path, no FORGE_SUPERVISOR env, no config env vars |
| Exploitable code | 0 | None found |
Verdict: Right scope, no malicious code, but 7 critical bugs make it completely non-functional. The iptables rules fail silently, privilege drop creates a redirect loop, SNI extraction returns empty strings, and proxied connections lose their initial bytes. Needs significant rework before merge.
Critical bugs fixed: 1. iptables: add -t nat (REDIRECT only valid in nat table) 2. privdrop: remove from supervisor; exec.go sets UID 1000 on child only 3. proxy: convert port from network byte order (binary.BigEndian.Uint16) 4. proxy: replay consumed bytes to upstream via peekReader 5. sni: fix name_length offset (was off by one — read name_type as length) 6. proxy: use io.Copy (no shared buffer race) 7. Dockerfile: remove adduser from scratch; copy /etc/passwd from builder Security fixes: 8. privdrop: add setgroups(gid) before setgid 9. privdrop: drop capability bounding set via PR_CAPBSET_DROP 10. exec: make Setctty conditional on isStdinTTY() 11. http: fix Host: off-by-one (5 chars, not 4) 12. main: support FORGE_SUPERVISOR_* env vars (POLICY_PATH, PORTS) 13. main: default policy path /etc/forge/egress_allowlist.json
|
@TJUEZ — Follow-up review of the fix commit ( Original 7 Critical Bugs — Status After Fix
Original 7 Security Concerns — Status After Fix
Remaining Critical Issues (3)1. Consumed bytes replayed in WRONG DIRECTION (
|
| Category | Result |
|---|---|
| Original critical bugs fully fixed | 4 of 7 (iptables, priv drop, port order, shared buffer) |
| Original critical bugs still broken | 2 (consumed bytes wrong direction, SNI offset) |
| Original critical bugs partially fixed | 1 (Dockerfile — adduser ok, RUN in scratch new) |
| Security concerns resolved | 5 of 7 |
| New issues introduced | 3 (Dockerfile RUN, duplicate COPY, HTTP consumed incomplete) |
| Exploitable code | 0 |
Verdict: Solid improvement. The iptables/privilege/port/buffer fixes are correct. Two critical issues remain — the consumed bytes replay goes in the wrong direction (upstream never sees initial bytes) and SNI extraction still returns empty strings. One more pass should get this to a mergeable state.
Summary
Implements Phase 1 MVP of the Container Sandbox Supervisor for #35.
The supervisor is a lightweight static binary that runs as PID 1 inside Forge containers, providing transparent TCP proxy with domain allowlist enforcement via iptables REDIRECT + SO_ORIGINAL_DST.
What was built
main.goiptables.goproxy.gosni.gohttp.gopolicy.goprivdrop.goexec.gohealth.goaudit.goDockerfileintegration_test.goTotal: ~1,124 lines
Architecture
Test results
Closes
Closes #35
Generated by OpenClaw AI agent — scout v3 team