Component
forge-core (registry, tools, security, channels, LLM), forge-cli (commands, TUI wizard, runtime), forge-skills (skill parser, compiler, analyzer, trust)
Description
Forge's current egress enforcement relies on two app-level mechanisms that are bypassable:
- EgressEnforcer — wraps Go's
http.RoundTripper (only catches Go HTTP calls)
- EgressProxy — localhost HTTP forward proxy with
HTTP_PROXY env injection (voluntary — programs can ignore it)
Any subprocess that ignores HTTP_PROXY or makes raw TCP/UDP connections reaches the internet directly. The K8s NetworkPolicy Forge generates only allows TCP 80/443 to any destination — domain enforcement is advisory only.
This phase introduces a container sandbox supervisor (forge-supervisor) — a lightweight static binary that runs as PID 1 inside Forge-built containers, providing kernel-level network isolation via iptables, DNS filtering, seccomp syscall filtering, and a policy engine.
Depends on: Phase 1 (C-1 through C-3 must land first — the supervisor's DomainMatcher inherits the same SSRF bypass issues if unfixed)
Reference: PLAN-04-CONTAINER-SANDBOX-SUPERVISOR.md
Bypass Vectors Addressed
| Vector |
Current Mitigation |
After Supervisor |
| Go HTTP client |
EgressEnforcer RoundTripper |
EgressEnforcer + transparent proxy |
| Subprocess HTTP |
HTTP_PROXY env var (voluntary) |
iptables REDIRECT to transparent proxy |
| Raw TCP socket |
None |
iptables REDIRECT + SNI/Host extraction |
| DNS exfiltration |
None |
DNS proxy with domain filtering |
| Dangerous syscalls |
None |
Seccomp profile filtering |
What's NOT Covered by Phases 1-4
All items below are new work not addressed by the existing security phases:
forge-supervisor Go module — New PID 1 binary for containers (~2,100 lines)
- Transparent TCP proxy — iptables uid-owner REDIRECT + SO_ORIGINAL_DST + TLS SNI extraction
- DNS proxy — Intercept UDP 53, filter by allowed domains, block exfiltration
- Seccomp profile generation — Block dangerous syscalls (mount, ptrace, unshare, bpf, etc.)
- Policy engine — Phase 1: DomainMatcher reuse; Phase 2: OPA/Rego for custom policies
- Privilege drop — setuid/setgid to UID 1000, prctl(PR_SET_NO_NEW_PRIVS), drop all capabilities
- Build pipeline stages — RegoStage (egress_allowlist → policy.rego), SeccompStage (skill reqs → seccomp.json)
- Dockerfile template — Supervisor ENTRYPOINT, multi-stage with supervisor image
- K8s deployment template — SecurityContext (readOnlyRootFilesystem, capability restrictions, proper probes, emptyDir volumes)
- forge.yaml supervisor config — New
supervisor: section with opt-in enablement
- Health/denial/metrics endpoints —
/healthz, /denials, /metrics on port 15000
- NDJSON audit logging — Structured denial events on stdout
Also Covers Deferred Items from FORGE-SECURITY-UPDATE.md
| # |
Issue |
Why Covered Here |
| M-10 |
TOCTOU/symlink swap in file operations |
Supervisor's read-only rootfs + seccomp (blocking mount/unshare) reduces TOCTOU attack surface |
| M-12 |
OTLP endpoint URL sanitization |
Supervisor's egress enforcement covers OTLP endpoints going to unintended destinations |
Expected behavior
After Phase 5, Forge containers have 6 security layers (up from 1):
- K8s NetworkPolicy (existing)
- K8s SecurityContext (readOnlyRootFilesystem, capability drop)
- Seccomp syscall filter
- Transparent TCP proxy (iptables REDIRECT + domain allowlist + SNI extraction)
- DNS proxy (domain-filtered DNS resolution)
- App-level EgressEnforcer + EgressProxy (existing)
All egress from the agent process (UID 1000) is redirected through the supervisor's transparent proxy. Connections to domains not in the allowlist are RST'd and logged. DNS queries for non-allowed domains are refused. Dangerous syscalls are blocked by seccomp.
Actual behavior
Only 1 real layer (EgressEnforcer, in-process Go only). Subprocesses, raw TCP, and DNS are unprotected.
Tasks
Supervisor Phase 1: MVP (Weeks 5-6)
Transparent TCP proxy with domain allowlist enforcement inside container.
Supervisor Phase 2: Build Pipeline Integration (Week 7)
forge build produces supervisor-enabled containers when configured.
Supervisor Phase 3: DNS Proxy + Seccomp (Week 8)
Close DNS exfiltration vector. Apply syscall filtering.
Supervisor Phase 4: OPA Policy Engine (Weeks 9-10)
Support custom Rego policies beyond simple domain matching.
Deferred Items Now Covered
Architecture
Container start
│
▼
forge-supervisor (PID 1, UID 0)
├─ 1. Load policy (/etc/forge/egress_allowlist.json)
├─ 2. Setup iptables (REDIRECT UID 1000 TCP → :15001, UDP 53 → :15002)
├─ 3. Start transparent TCP proxy (:15001) — SNI/Host extraction + policy eval
├─ 4. Start DNS proxy (:15002) — domain-filtered resolution
├─ 5. Start health endpoint (:15000)
├─ 6. Apply seccomp profile to child
├─ 7. Drop privileges (setuid 1000, drop all caps, PR_SET_NO_NEW_PRIVS)
└─ 8. Fork+exec agent (UID 1000)
Estimated Effort
| Sub-phase |
New Code |
Modified Code |
Timeline |
| Supervisor MVP |
~950 lines |
~0 |
Weeks 5-6 |
| Build pipeline |
~220 lines |
~365 lines |
Week 7 |
| DNS + Seccomp |
~560 lines |
~0 |
Week 8 |
| OPA engine |
~370 lines |
~70 lines |
Weeks 9-10 |
| Total |
~2,100 lines |
~435 lines |
6 weeks |
Risks
| Risk |
Mitigation |
| iptables unavailable in minimal images |
Use nftables fallback; document base image requirements |
| CAP_NET_ADMIN denied by cluster policy |
Graceful fallback to HTTP_PROXY mode with warning |
| Supervisor crash kills agent (PID 1) |
Fork model: supervisor stays PID 1, agent is child |
| SNI not present (raw TCP without TLS) |
Fall back to reverse DNS → resolved IPs of allowed domains → deny (fail closed) |
| Performance overhead |
Simple relay, no TLS termination. <1ms per connection. |
Component
forge-core (registry, tools, security, channels, LLM), forge-cli (commands, TUI wizard, runtime), forge-skills (skill parser, compiler, analyzer, trust)
Description
Forge's current egress enforcement relies on two app-level mechanisms that are bypassable:
http.RoundTripper(only catches Go HTTP calls)HTTP_PROXYenv injection (voluntary — programs can ignore it)Any subprocess that ignores
HTTP_PROXYor makes raw TCP/UDP connections reaches the internet directly. The K8s NetworkPolicy Forge generates only allows TCP 80/443 to any destination — domain enforcement is advisory only.This phase introduces a container sandbox supervisor (
forge-supervisor) — a lightweight static binary that runs as PID 1 inside Forge-built containers, providing kernel-level network isolation via iptables, DNS filtering, seccomp syscall filtering, and a policy engine.Bypass Vectors Addressed
What's NOT Covered by Phases 1-4
All items below are new work not addressed by the existing security phases:
forge-supervisorGo module — New PID 1 binary for containers (~2,100 lines)supervisor:section with opt-in enablement/healthz,/denials,/metricson port 15000Also Covers Deferred Items from FORGE-SECURITY-UPDATE.md
Expected behavior
After Phase 5, Forge containers have 6 security layers (up from 1):
All egress from the agent process (UID 1000) is redirected through the supervisor's transparent proxy. Connections to domains not in the allowlist are RST'd and logged. DNS queries for non-allowed domains are refused. Dangerous syscalls are blocked by seccomp.
Actual behavior
Only 1 real layer (EgressEnforcer, in-process Go only). Subprocesses, raw TCP, and DNS are unprotected.
Tasks
Supervisor Phase 1: MVP (Weeks 5-6)
forge-supervisor/Go module (go.mod,main.go)supervisor/iptables.go(~80 lines)SO_ORIGINAL_DST—supervisor/proxy.go(~200 lines)supervisor/sni.go(~100 lines)supervisor/http.go(~40 lines)DomainMatcherfrom forge-core —supervisor/matcher.goegress_allowlist.json, build matcher —supervisor/policy.go(~60 lines)supervisor/privdrop.go(~50 lines)supervisor/exec.go(~80 lines)/healthz,/denials) —supervisor/health.go(~60 lines)supervisor/audit.go(~40 lines)supervisor/Dockerfilesupervisor/integration_test.goSupervisor Phase 2: Build Pipeline Integration (Week 7)
supervisorsection toForgeConfigtypes —forge-core/types/config.goforge-core/validate/schema.goRegoStage(egress_allowlist → policy.rego) —forge-cli/build/rego_stage.goSeccompStage(skill reqs → seccomp.json) —forge-cli/build/seccomp_stage.goDockerfileStagetemplate for supervisor —forge-cli/templates/Dockerfile.tmplK8sStagetemplates (SecurityContext, probes, volumes, resources) —forge-cli/templates/deployment.yaml.tmplforge-cli/build/pipeline.goforge initTUI to offer supervisor optionSupervisor Phase 3: DNS Proxy + Seccomp (Week 8)
supervisor/dns.go(~150 lines)supervisor/seccomp.go(~80 lines)/etc/forge/seccomp.jsonSupervisor Phase 4: OPA Policy Engine (Weeks 9-10)
supervisor/opa.gosupervisor/policy.go/proc/PID/exereadlink for binary identity —supervisor/procfs.goDeferred Items Now Covered
Architecture
Estimated Effort
Risks