No reviewers
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Creatidy/creatidy-kernel!84
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-53-codex-oci-worker-proof"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Bounded #53 continuation (owner directive): prove that the actual Codex app-server and its native tool paths run inside the exact #78 rootless OCI worker boundary, with enforcement independent of Codex approval callbacks — followed by owner-directed security corrections of the collection trust boundary, the container-state lifecycle observation, and the shared worker-status reader. No synthetic worker substitutes for the harness; no
src/product behavior changes; #50/#78 boundaries and evidence preserved.Native isolation proof (observed)
CREATIDY_TEST_OCI_TOOLROOT=/tmp/kilo/kernel78-tooling make codex-oci-proof— observed 2026-10-10 at the delivered HEAD9466187: 22 items passed, 0 failed, 0 native skips (11 native cells + 7 host-side collection-safety cells + 4 host-side lifecycle-observation cells; skips are explicit UNPROVED without the pinned toolroot/binary). The fail-closed worker-status reader is gated by 3 further host-side cells undermake oci-worker-proof(29 passed there, #78 regression included).initializehandshake (productionCodexStdiotransport via a generated per-attempt wrapper),thread/start/turn/start/turn/completedinside OCI; native rollout JSONL in a fresh syntheticCODEX_HOME.exec_commandtool op reading and modifying only the disposable candidate workspace; read-only rootfs write refused (Read-only file systemobserved in-boundary).exec_commandPTY and directcommand/exec(no thread) — plussetsiddetached descendant;turn/interruptis not settlement;podman stopsettles the tree (host/procscan); bystander survives.approvalPolicy: "never"+sandbox: "danger-full-access"(recorded verbatim in evidence) — enforcement comes from the boundary, not native approvals or Codex's own sandbox.AttemptExpiredforturn/start/command/exec.executedat relay,reply_lostat worker (receipt log is truth).Security corrections (owner-directed)
Collection trust boundary (symlink-following collector). The original collector traversed the worker-controlled workspace with
rglob/is_file/stat— a worker-created symlink to a host path could cause an unauthorized host-side read during collection. Reproduced safely with synthetic files, remediated fail-closed (tools/codex_oci_proof/collect.py): authorized candidate roots only; regular-file-only; symlinks refused in every component; descriptor-pinned single-component lookups withfstaton the exact descriptor read;O_NONBLOCK; bounded reads/entries/depth; refusals as recorded failures. Publishable artifacts (only fromcandidate/) have exact bytes preserved and digest-bound under the controller-ownedcollected/tree; private runtime state is inventoried separately. Native regression: worker-side symlinks refused by name with the prohibited host target never opened; no worker-controlled path is kernel-resolved after enumeration anywhere in the delivery.Container-state lifecycle observation. The shared observer mapped every nonzero
podman container existsexit to "absent", conflating confirmed absence (exit 1) with podman 125-style engine/storage errors, timeouts and lost observations. It now returns a typed outcome —exists(0) /absent(1, confirmed) /unknown(everything else) — and all callers are reconciled:CodexAttempt.collect()authorizes only on confirmed absent (unknown is a typed refusal);dispose()terminates on every non-absent observation; #78 harness callers follow the same rule. Deterministic synthetic cells cover exit codes 0, 1, 125, other nonzeros, timeout and lost observation, and prove code 125 can neither authorize collection nor count as settlement.Worker-status reader. The #78 harness
worker_status()read its worker-controlled status path with symlink-following primitives. The bounded-regular reader was extracted into the #78 package (tools/oci_worker_poc/saferead.py— dependency direction preserved: the #78 harness imports only its own package; the #53 collector re-exports the same primitives) andworker_status()now routes through it: a planted symlink is refused before any open, non-regular replacements and oversized files raise, absence stays truthful, malformed JSON raises. Regression cells prove a worker-created symlink cannot causeworker_status()to read a host-only JSON file.Versions / provenance
Codex
0.159.3standalone musl (hash-pinned, mounted read-only, fresh syntheticCODEX_HOME, owner Codex state never read); podman 6.1.3 / crun 1.30.1 / conmon 2.2.1 / busybox from the #78 toolrootprovenance.json; deterministic controller-built image; protocol inventory generated by the pinned binary. Isolation policy flags flag-for-flag identical to #78; cgroup budget larger by design (disclosed). Seccomp: identical deny set,clone3ENOSYS instead of EPERM (upstream practice; review-verified) — compatibility correction, not a weakening.Dispositions for the five #78 limitations
docs/architecture/codex-oci-native-proof.md: seccomp clone-flags residual UNPROVEN (named owner decision); settlement REMEDIATED (authoritative container lifecycle + non-cooperative argv markers); instantaneous FD revocation unsupported by design, recorded as fact; single-UID mapping unchanged (deployment prerequisite); relay↔durable-authority integration named remaining work.
Gates (all at delivered HEAD
9466187)make check(1428 passed / 85 skipped / 81 subtests; secrets clean;git diff --checkclean),make package-check,make audit(clean),make oci-worker-proof(29 passed),make codex-oci-proof(22 passed). Canonical CI #2414 SUCCESS on exact HEAD9466187(2407–2412 success on prior commits).Review status (owner exception: budget 10 → 12; 11/12 consumed; ordinal 12 unused)
All ten pre-exception ordinals preserved (1–3 COMMENT remediated; 4 APPROVE at
7e2a021; 5–8 COMMENT on each security HEAD with the trust findings independently confirmed resolved; 9 APPROVE at7aad45e; 10 REQUEST_CHANGES with two non-blocking P3s). Under the owner exception:Non-goals
#53 stays open and gated; not merged by this work; no release/deploy/GO; no live or paid inference; no privileged host changes; no product contract changes; no complete-AC4 conformance claim. Pre-existing symlink-following reads in #78 native-only synthetic cells (whose in-boundary worker is the repository's own deterministic script) are recorded as an owner-decision residual outside this delivery's authorized scope.
Refs: #53, #78, #50, #79, #80.
- O_NONBLOCK on every fail-closed open (collector file opens and the bounded regular reader): a live racer swapping a workspace entry to a FIFO can no longer block the controller's open; post-open fstat S_ISREG still refuses non-regular objects, and O_NONBLOCK is a no-op for regular reads. - worker_observations now distinguishes absence (pre-exec launcher never ran: {}) from tampering (planted symlink, non-regular replacement, oversized file: raises) so evidence fidelity cannot mask worker tampering as absence. - All test-side reads of worker-controlled workspace/codex-home paths routed through the same trust boundary as collection: a fail-closed bounded reader for fixed paths, collector-based discovery plus bounded reads for session rollouts, and lstat-based existence/size checks so planted symlinks never count and targets are never followed. Remediation for review ordinal 5 (COMMENT: trust-boundary finding confirmed resolved; 2 non-blocking P3): frozen HEADdcf321d3d6, base73e3af45c9. Gates at this commit: make check 1419/85, package-check, audit clean, codex-oci-proof 16, oci-worker-proof 26; native suite re-run 16/16 after remediation.