Repository navigation
Conversation
…N_WORKLOAD_UID Every child ran as PID 1's root, so the SO_PEERCRED secrets check always passed (workload uid == harness uid), the iptables REDIRECT (which exempts the harness uid) did not apply to the workload, and tls.key was readable. Spawn via CommandExt uid/gid (gid defaults to uid; std clears supplementary groups). The secrets and OTLP sockets are chmod 0666 so the unprivileged workload can still connect; SO_PEERCRED stays the authorization.
The kernel cmdline splits on whitespace and strips quotes, so argv like 'python main.py' and JSON egress lists arrived mangled. spawn.json (workload_cmd, env, egress_rules, workload_uid/gid; all optional, unknown fields ignored) now takes precedence over boot-args; typed fields beat free-form env. Malformed file: fatal in prod, warn + cmdline in dev. The cert material is copied into a root-only 0700 dir and the drive is unmounted, so tls.key and spawn.json are unreachable by the workload uid regardless of the image's file modes.
…d file tools http_fetch buffered the whole body before checking the 1 MiB cap and shell_exec used unbounded .output(). Both now stream with a bounded read and truncate with a marker; shell_exec runs as the workload uid under the timeout. New read_file / write_file / list_dir tools are confined to LANTERN_WORKSPACE (default /workspace): canonicalize + prefix check, leaf O_NOFOLLOW|O_NONBLOCK, hard links rejected, writes chowned to the workload.
…start without a workload uid Children inherited the harness's whole environment, including LANTERN_HARNESS_EXEC_TOKEN, LANTERN_AGENT_INSTANCE_TOKEN and the TLS key path. as_workload() now env_clear()s and passes the harness env minus the LANTERN_* namespace (except a short non-secret allowlist: VM/run id, socket paths, workspace, trace parent, LANTERN_WORKLOAD_*), then drops the uid. Used by the supervisor, vm exec (tty and not) and shell_exec. The prod 'LANTERN_WORKLOAD_UID missing' check ran in the secrets task, racing the supervisor; parse_env now fails first. The secrets check stays. fs tools open through openat2(RESOLVE_BENEATH|RESOLVE_NO_SYMLINKS) on a root fd on Linux, closing the parent-dir swap window after the path check; pre-5.6 kernels (ENOSYS) and non-Linux keep the plain open.
…t context rust:1.85 cannot build the current Cargo.lock, build.rs needs protoc, and 'COPY . .' from services/harness could never reach ../../packages/proto. Build from the repo root; a per-Dockerfile .dockerignore keeps the context to packages/proto + services/harness.
🔎 Codex cross-audit (agent:audit)Blocking
High
I did not run tests; the workspace is read-only and even |
🛡️ Vuln scan — ❌ vulnerable dependency found |
🔷 Gemini cross-audit (agent:audit-gemini)Blocking Issues
High Severity & Architectural Invariants
Edge Cases & Minor Regressions
|
Part 4 of 10 of the GA next-gen stack (split from #254 so each AI review fits its budget). Base:
ga/03-bridges. Merge in order with a merge commit (not squash) so the stack stays intact.Full context, verification results and needs-human list: #254 and
docs/roadmap/2026-10-nextgen-sandbox-and-harness.md.Commits in this part: