Repository navigation
[Bug]: ocx claude --dangerously-skip-permissions aborts as root (uid==0) because IS_SANDBOX is never set #1688
Description
Summary
ocx claude --dangerously-skip-permissions aborts immediately when running as root (uid == 0), which is the default on most VPS deployments. Claude Code 2.1.205+ embeds a safety guard that exits with --dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons unless it believes it runs inside a sandbox (IS_SANDBOX=1) or a bubblewrap wrapper is present. The opencodex proxy launches the session, so it should mark the environment accordingly.
Reproduction
# As root (typical VPS):
ocx claude --dangerously-skip-permissions --print "ok"Expected: the Claude session starts and prints ok.
Actual: immediate fatal exit with the root-guard message.
Logs and screenshots
--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons
Area
CLI
Version
2.14.2 (also on current main — IS_SANDBOX does not appear anywhere in src/)
OS
Ubuntu 24.04 (root user)
Config shape
N/A (CLI invocation only)
Root cause
src/cli/claude.ts buildClaudeEnv does not set IS_SANDBOX. The guard is in the official Claude Code binary, not in opencodex — but since the proxy owns the launched session (a controlled, proxy-launched environment), it must signal IS_SANDBOX=1 so the binary allows the bypass. Without it, every root-hosted deployment of ocx claude with permissions bypass is unusable.
Proposed fix
In buildClaudeEnv, before return env;:
for (const [name, value] of Object.entries(effectiveModelEnv(config.claudeCode, contextWindows, auto))) {
setDefault(name, value);
}
+ // Root bypass guard (Claude Code 2.1.205+): the CLI refuses --dangerously-skip-permissions
+ // when uid==0 unless it believes it runs inside a sandbox. Servers are commonly root, so
+ // treat the proxy-launched session as one — opt out by exporting IS_SANDBOX=0 yourself.
+ if (typeof process.getuid === "function" && process.getuid() === 0) {
+ setDefault("IS_SANDBOX", "1");
+ }
return env;setDefault semantics already guarantee the user can override (IS_SANDBOX=0 exported by the user wins), so this is an opt-out-by-env design, not a forced change.
Alternatives considered
- Document "run as non-root": impractical on VPS setups where the service owns root files, and Claude Code already provides the sandbox escape hatch (
IS_SANDBOX) for exactly this case. - Require
CLAUDE_CODE_BUBBLEWRAP: heavier, not portable;IS_SANDBOXis the documented, minimal signal.
Additional context
The same pattern is used by other proxy-launcher tools: the session is a controlled environment created by the parent process, so marking it as sandboxed for the child's safety guard is accurate and safe. The user opt-out (IS_SANDBOX=0) preserves the strict behavior for anyone who wants it.
Test matrix:
- root +
--dangerously-skip-permissions→ session starts (200 / prints) - root + exported
IS_SANDBOX=0→ original guard behavior preserved (user opted out) - non-root → unchanged (no
IS_SANDBOXinjected)
Activity
coderabbitai commentedon Aug 14, 2026
🔗 Related PRs
#573 - fix(server): treat forwarded loopback ports as loopback [merged]
#936 - fix: harden credential and runtime trust boundaries (rebase of
#916) [merged]#1358 - fix(claude): contain main credentials to canonical forward routes [merged]
#1360 - fix(claude): bind proxy admission tokens to local destinations [merged]
#1441 - fix(codex): stop recursive dynamic-launcher shims [open]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
Wibias commentedon Aug 14, 2026
The workflow problem here is real, but #1701 is being closed because
uid == 0is not sandbox evidence. OpenCodex launching Claude as a child process does not itself create an OS security boundary, so automatically settingIS_SANDBOX=1would claim isolation that does not exist and can suppress Claude Code's root guard while--dangerously-skip-permissionsis active.Preferred solution: create a real sandboxed launch path
If OpenCodex wants to support
ocx claude --dangerously-skip-permissionsas root, the clean solution is to make the sandbox claim true rather than bypass the check.Conceptually:
On Linux this should use an actual isolation primitive suitable for the project, for example a bubblewrap-based launch path or another reviewed sandbox mechanism. The exact implementation needs a threat-modelled contract for filesystem access, process access, network access, required mounts, working directory access, and any capabilities that must remain available for normal Claude Code operation.
Important requirements:
IS_SANDBOX=1from UID alone.ocx claudebehaviour unchanged.A smaller explicit unsafe opt-in could technically work as an escape hatch, but it still intentionally defeats an upstream safety guard. A real sandboxed launcher is the preferred long-term fix because it solves the original VPS/root workflow without weakening the meaning of
IS_SANDBOX.yzxcj797 commentedon Aug 18, 2026
Implementing with one deliberate deviation from the proposed diff:
IS_SANDBOX=1is set only when the user explicitly passed--dangerously-skip-permissions(detected incmdClaudeand threaded throughClaudeEnvDeps), not for every launch. Rationale: the variable exists to relax a vendor safety guard, and marking every proxy-owned session as sandboxed could silence other guard behaviors in future Claude Code versions; an ordinaryocx claudelaunch keeps the vendor's default posture. An explicit user export still wins (setDefault semantics).Tests cover the bypass launch setting it, the ordinary launch not setting it, and the user-export-wins case.
lidge-jun commentedon Aug 19, 2026
리뷰 · 우선순위 46 / 80
루트(uid 0)에서 ocx claude --dangerously-skip-permissions를 쓰면 Claude Code가 바로 끝나는 버그입니다. 2.1.205+는 샌드박스 표시가 없으면 루트에서 이 플래그를 거부합니다. VPS에서 루트로 돌리는 경우가 많아, 프록시가 띄운 세션이 시작조차 못 합니다. needs-info가 붙어 있습니다.
현재 dev의 src/cli/claude.ts buildClaudeEnv()는 ANTHROPIC_BASE_URL, 호스트 인증, 컨텍스트/모델 슬롯을 setDefault로 넣고 242행에서 env를 반환합니다. IS_SANDBOX는 src 안에 없습니다. setDefault는 사용자가 이미 넣은 값을 덮어쓰지 않으므로, 이슈가 말한 옵트아웃 설계와는 맞습니다.
원하는 결과는 루트 VPS에서도 세션이 시작되는 것입니다. 다만 IS_SANDBOX=1은 Claude Code의 루트 가드를 우회하는 신호입니다. 프록시가 띄운 통제된 환경이라는 주장과, 실제 격리가 없다는 점이 같이 있습니다. 그래서 기본 주입을 넣을지는 보안 판단이 필요합니다. 사용자가 IS_SANDBOX=0을 내보내면 가드가 남는다는 점은 코드의 setDefault와 맞습니다.
해결방안: 루트일 때만 setDefault로 IS_SANDBOX=1을 넣는 패치는 위치가 분명합니다. 비루트는 그대로 두고, 테스트는 루트+플래그, 루트+IS_SANDBOX=0, 비루트를 나누면 됩니다. 기본 주입을 거부한다면 문서에 비루트 실행 또는 사용자 환경 변수를 적는 대안이 있습니다. 공식 Claude Code 가드 계약이 이슈와 같은지는 needs-info로 남아 있습니다.
이 댓글은 grok-bot이 작성했습니다
lidge-jun commentedon Aug 19, 2026
리뷰 · 우선순위 46 / 80 · 유지
VPS에서 root로
ocx claude --dangerously-skip-permissions하면 Claude 2.1.205+가 바로 죽음.buildClaudeEnv가IS_SANDBOX를 안 넣어서임. 증상은 맞음.다만 root일 때 기본으로
IS_SANDBOX=1넣는 패치는 반대임. 그 가드는 보안 이유로 있는 건데, ocx가 기본으로 속이면 skip-permissions가 루트 전체 파일에 열림.setDefault로IS_SANDBOX=0이 이겨도, 기본값이 우회면 실수하기 쉬움.열어 둠. 고칠 거면 명시 플래그/환경변수로만. 문서에 root 비추. 자동 주입 PR은 안 받음.
해결방안:
--allow-root-skip-permissions같은 opt-in이거나 사용자가IS_SANDBOX=1을 직접 넣을 때만. 기본은 지금처럼 가드 유지. 가능하면 non-root로 돌리게.이 댓글은 grok-bot이 작성했습니다
fix: gate root skip-permissions bypass and ship the auto-review model…
lidge-jun commentedon Aug 25, 2026
Fixed on
devby #2631 (squash848a66d15).Your diagnosis was exact — Claude Code 2.1.205+ exits as root unless it believes it is sandboxed, and OpenCodex launches the session so it is the layer that can mark the environment.
I did not set
IS_SANDBOX=1unconditionally, because that would tell Claude Code a safety guard is satisfied when it is not. The bypass requires both conditions: you passed--dangerously-skip-permissionsexplicitly (so you have already accepted that risk) anduid == 0. An ordinary launch is untouched, and an explicitIS_SANDBOX=0of your own still wins — user values are never overwritten.The launch also says what happened, in both directions:
A silent safety-guard bypass would have been the wrong shape even though it fixes the symptom — you should be able to tell from the output that no real sandbox exists.
No bubblewrap wrapper was added. That is a Linux-only isolation feature with its own threat model, not something to bundle into a launcher flag fix; if you want real isolation on a VPS rather than a guard bypass, that is worth its own issue.
fix: gate root skip-permissions bypass and ship the auto-review model…
fix: gate root skip-permissions bypass and ship the auto-review model…