Environment
- OS: macOS (host)
- Runtime: NemoClaw CLI v0.0.59
- Sandbox: mutable-test
- Inference provider: nvidia/nemotron-3-super-120b-a12b via nvidia-prod (cloud)
- Platform type: default "mutable" sandbox (no shields) per wizard and shields status
Pre-conditions
- NemoClaw CLI installed on host.
- No existing sandbox named
mutable-test.
- Docker / OpenShell working;
nemoclaw onboard --name mutable-test succeeds.
Steps to Reproduce
1. On host, create sandbox:
nemoclaw onboard --name mutable-test
# Complete wizard with default permission mode (mutable, shields down).
2. Check shields state:
nemoclaw mutable-test shields status
Actual output:
Shields: NOT CONFIGURED (default mutable state)
Config is mutable. Run `nemoclaw <sandbox> shields up` to opt into lockdown.
3. Check sandbox status:
nemoclaw mutable-test status
Key details:
- Permissions: not configured (default mutable state)
filesystem_policy.read_write includes /sandbox/.openclaw
4. Connect to sandbox:
nemoclaw mutable-test connect
5. Inside sandbox, inspect permissions before doctor:
stat -c '%a %U:%G' /sandbox/.openclaw/openclaw.json
stat -c '%a %U:%G' /sandbox/.openclaw
Actual initial values:
/sandbox/.openclaw/openclaw.json → 660 sandbox:sandbox
/sandbox/.openclaw → 2770 sandbox:sandbox
6. Run doctor:
openclaw doctor --fix; echo "doctor_exit:$?"
Actual output highlights — doctor warns "State directory permissions are too open" and "Config file is group/world readable," then applies:
- Tightened permissions on $OPENCLAW_HOME/.openclaw to 700
- Tightened permissions on $OPENCLAW_HOME/.openclaw/openclaw.json to 600
Attempts to install shell completions and fails with:
Error: Failed to install completion: EACCES: permission denied, open '/sandbox/.bashrc'
doctor_exit:1
7. As sandbox user, try to append to config (succeeds, as expected for mutable):
echo 'smoke' >> /sandbox/.openclaw/openclaw.json; echo "write_exit:$?"
8. Still inside sandbox, try to write as gateway user:
su -s /bin/sh gateway -c "printf 'gateway-probe\n' >> /sandbox/.openclaw/openclaw.json"; echo "gateway_write_exit:$?"
Actual output:
Password:
su: System error
gateway_write_exit:1
9. Exit sandbox and install a test skill (works):
rm -rf /tmp/nemoclaw-test-skill && mkdir -p /tmp/nemoclaw-test-skill
printf '%s\n' '---' 'name: nemoclaw-test-skill' 'description: smoke test skill' '---' 'Smoke test skill.' > /tmp/nemoclaw-test-skill/SKILL.md
nemoclaw mutable-test skill install /tmp/nemoclaw-test-skill; echo "skill_exit:$?"
Actual output:
✓ Skill 'nemoclaw-test-skill' installed
skill_exit:0
10. Reconnect, verify skill presence (works):
nemoclaw mutable-test connect
test -f /sandbox/.openclaw/skills/nemoclaw-test-skill/SKILL.md; echo "installed_skill=$?"
Actual output:
Expected Behavior
Per NemoClaw's mutable-sandbox contract:
- In default mutable mode, permissions should allow both the sandbox user and the gateway user (member of sandbox group) to read/write
/sandbox/.openclaw/openclaw.json and create files under /sandbox/.openclaw.
- Expected stat results in a healthy mutable sandbox:
/sandbox/.openclaw/openclaw.json → 664 sandbox:sandbox
/sandbox/.openclaw → 2775 sandbox:sandbox
Group-write and setgid bit ensure gateway can persist UI toggles.
openclaw doctor --fix should not silently lock down mutable sandboxes — it should respect NemoClaw's mutable/locked-down mode and only apply chmod 700/600 when shields are up or explicit hardening is requested.
- Gateway write test should succeed (
exit 0) in mutable sandboxes.
openclaw doctor --fix should exit 0 in a default mutable sandbox (or clearly mark permission tightening as "optional hardening").
Actual Behavior
After doctor runs, it tightens permissions to:
/sandbox/.openclaw → 700 sandbox:sandbox
/sandbox/.openclaw/openclaw.json → 600 sandbox:sandbox
This contradicts the documented mutable-mode expectation (group-writable for gateway).
openclaw doctor --fix exits non-zero due to:
Error: Failed to install completion: EACCES: permission denied, open '/sandbox/.bashrc'
doctor_exit:1
su -s /bin/sh gateway ... fails with:
su: System error
gateway_write_exit:1
Gateway user cannot write openclaw.json. This breaks the "mutable default" contract and causes control-UI configuration changes to silently fail to persist.
shields status and status continue to report "default mutable state," but actual file permissions now match a locked-down configuration — a state/UX mismatch.
Impact
- Gateway-driven config mutations (e.g. UI toggles) cannot be written after doctor runs, even though the CLI reports "mutable."
- Users following the recommended
openclaw doctor --fix flow in default mutable sandboxes end up in a partially locked-down config without realizing it.
Proposed Fixes / Questions
- Mode-aware doctor:
openclaw doctor should detect mutable vs locked-down mode and only apply chmod 700/600 when shields are up or explicit hardening is requested.
- Restore group-writable contract in default mutable sandboxes:
~/.openclaw → 2775 sandbox:sandbox
openclaw.json → 664 sandbox:sandbox
- Non-fatal completion install failure: Treat
EACCES on /sandbox/.bashrc as a warning so doctor can still exit 0.
- Docs clarification: Clarify whether
openclaw doctor --fix is intended to change permissions away from NemoClaw's mutable defaults and how that interacts with shields status.
Environment
Pre-conditions
mutable-test.nemoclaw onboard --name mutable-testsucceeds.Steps to Reproduce
1. On host, create sandbox:
nemoclaw onboard --name mutable-test # Complete wizard with default permission mode (mutable, shields down).2. Check shields state:
Actual output:
3. Check sandbox status:
Key details:
filesystem_policy.read_writeincludes/sandbox/.openclaw4. Connect to sandbox:
5. Inside sandbox, inspect permissions before doctor:
Actual initial values:
6. Run doctor:
Actual output highlights — doctor warns "State directory permissions are too open" and "Config file is group/world readable," then applies:
Attempts to install shell completions and fails with:
7. As sandbox user, try to append to config (succeeds, as expected for mutable):
8. Still inside sandbox, try to write as gateway user:
Actual output:
9. Exit sandbox and install a test skill (works):
Actual output:
10. Reconnect, verify skill presence (works):
Actual output:
Expected Behavior
Per NemoClaw's mutable-sandbox contract:
/sandbox/.openclaw/openclaw.jsonand create files under/sandbox/.openclaw.openclaw doctor --fixshould not silently lock down mutable sandboxes — it should respect NemoClaw's mutable/locked-down mode and only applychmod 700/600when shields are up or explicit hardening is requested.exit 0) in mutable sandboxes.openclaw doctor --fixshould exit0in a default mutable sandbox (or clearly mark permission tightening as "optional hardening").Actual Behavior
After doctor runs, it tightens permissions to:
/sandbox/.openclaw→700 sandbox:sandbox/sandbox/.openclaw/openclaw.json→600 sandbox:sandboxThis contradicts the documented mutable-mode expectation (group-writable for gateway).
openclaw doctor --fixexits non-zero due to:su -s /bin/sh gateway ...fails with:Gateway user cannot write
openclaw.json. This breaks the "mutable default" contract and causes control-UI configuration changes to silently fail to persist.shields statusandstatuscontinue to report "default mutable state," but actual file permissions now match a locked-down configuration — a state/UX mismatch.Impact
openclaw doctor --fixflow in default mutable sandboxes end up in a partially locked-down config without realizing it.Proposed Fixes / Questions
openclaw doctorshould detect mutable vs locked-down mode and only applychmod 700/600when shields are up or explicit hardening is requested.~/.openclaw→2775 sandbox:sandboxopenclaw.json→664 sandbox:sandboxEACCESon/sandbox/.bashrcas a warning so doctor can still exit0.openclaw doctor --fixis intended to change permissions away from NemoClaw's mutable defaults and how that interacts withshields status.