Skip to content

[feature] GSTACK_CODEX_NO_SANDBOX env gate — Codex /review + /ship silently no-op in containers (bwrap can't create user namespaces) #1892

@dkoo761

Description

@dkoo761

Summary

Request a GSTACK_CODEX_NO_SANDBOX=1 opt-in env override that makes the Codex passes in /review and /ship run with Codex's OS sandbox bypassed, for environments where Codex's bubblewrap sandbox cannot create user namespaces (containers / devcontainers / Flatpak / WSL / Replit).

This mirrors the existing GSTACK_CHROMIUM_NO_SANDBOX=1 escape hatch that already exists for the /qa Chromium sandbox on AppArmor/root Linux — the Codex adversarial review has the exact same class of problem with no equivalent knob today.

Environment

  • gstack 1.55.0.0
  • codex-cli 0.136.0
  • Linux devcontainer on OrbStack (kernel 7.0.5-orbstack); unprivileged user namespaces are not permitted
  • bwrap not on PATH → Codex falls back to its bundled bubblewrap, which fails the same way

The problem

Every Codex pass in /review (always-on adversarial + the 200+ line structured review) and /ship (Step 11 adversarial) runs Codex with -s read-only. On Linux, -s read-only wraps every shell command Codex executes in bubblewrap, which needs unprivileged user namespaces. In a locked-down container these aren't available, so every command Codex runs (git diff, file reads) fails instantly:

bwrap: No permissions to create a new namespace, likely because the kernel
does not allow non-privileged user namespaces.
/bin/bash -lc 'git status --short' exited 1 in 0ms

Confirming the kernel side:

$ unshare --user true
unshare: unshare failed: Operation not permitted
$ cat /proc/sys/kernel/unprivileged_userns_clone   # knob doesn't exist on this kernel

The insidious part: it fails silently and looks like a clean review

  • A trivial Codex prompt with no shell commands succeeds (the model replies fine), which masks the problem.
  • But the review prompt instructs Codex to run git diff to see the changes. That command — and every command after it — exited 1 in 0ms with the bwrap error, so Codex produces output like "Could not run the requested commands … No repository status available" — i.e. a non-review.
  • Critically, codex exits 0, and the current error handling in ship/sections/adversarial.md / review/SKILL.md only treats stderr as an error when it matches auth / login / unauthorized / API key, a timeout, or empty output. A bwrap / namespace failure matches none of those, so gstack presents the empty "review" verbatim as a success. No gate, no warning. Users believe they got cross-model adversarial coverage when they got nothing.

Repro

# Works (no shell commands → sandbox never engaged) — this is the false reassurance
codex exec "Reply with exactly: PROBE_OK" -C "$PWD" -s read-only < /dev/null

# Fails (the real review path: Codex must run git/file reads)
codex exec "Run 'git status --short' then read README.md, summarize." \
  -C "$PWD" -s read-only -c 'model_reasoning_effort="low"' < /dev/null
# → bwrap: No permissions to create a new namespace; every command exits 1 in 0ms

Proposed solution

Add a GSTACK_CODEX_NO_SANDBOX opt-in (off by default; identical ergonomics to GSTACK_CHROMIUM_NO_SANDBOX). When set to 1, the Codex invocations in codex/SKILL.md, review/SKILL.md, and ship/sections/adversarial.md swap their sandbox flag:

  • codex exec passes: -s read-only--dangerously-bypass-approvals-and-sandbox
  • codex review (the 200+ line structured pass): it rejects -s and (per codex review --help) does not appear to accept --dangerously-bypass-approvals-and-sandbox — so use the config form -c sandbox_mode="danger-full-access" (please verify the exact accepted mechanism for the review subcommand).

The rationale is exactly what Codex's own flag help states: "Skip all confirmation prompts and execute commands without sandboxing. EXTREMELY DANGEROUS. Intended solely for running in environments that are externally sandboxed." A container/devcontainer is that externally-sandboxed environment, so Codex's nested OS sandbox is redundant there.

Secondary ask (independent of the env gate): stop the silent failure

Even without the env gate, the error handling should treat a sandbox/namespace failure as a Codex failure. Suggest adding bwrap / namespace / sandbox failed to the stderr error patterns so the review reports "Codex sandbox failed — set GSTACK_CODEX_NO_SANDBOX=1 if this environment is already externally sandboxed" instead of presenting an empty review as success. This is arguably the more important half — a silent no-op is worse than a loud skip.

Prior art / references

Affected files

  • codex/SKILL.md / codex/SKILL.md.tmpl
  • review/SKILL.md
  • ship/sections/adversarial.md (+ .tmpl)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions