fix(security): revert gateway auth token externalization#2482
Conversation
Reverts 51aa6af. The externalized token path breaks `openclaw tui` inside the sandbox — OpenClaw 2026.4.9 requires OPENCLAW_GATEWAY_TOKEN but the runtime injection fails under Landlock (non-root) and the token is no longer in openclaw.json where the TUI can read it. Restores build-time token generation in openclaw.json so gateways authenticate out-of-the-box again. The externalization will be re-introduced in a separate PR with deeper testing. Fixes #2480
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughGateway token handling was changed: a per-build random token is embedded into Changes
Sequence Diagram(s)sequenceDiagram
actor Build as Build Time
participant Docker as Dockerfile
participant Config as /sandbox/.openclaw/openclaw.json
participant StartSh as scripts/nemoclaw-start.sh
participant RcFiles as .bashrc/.profile
participant UserShell as User Interactive Shell
participant TUI as openclaw tui
Build->>Docker: generate per-build random token (secrets.token_hex(32))
Docker->>Config: embed token in openclaw.json (gateway.auth.token)
Note over StartSh,Config: container starts
StartSh->>Config: _read_gateway_token() parses gateway.auth.token
Config-->>StartSh: token value
StartSh->>StartSh: export OPENCLAW_GATEWAY_TOKEN
StartSh->>RcFiles: write/remove marked export blocks via export_gateway_token()
RcFiles->>UserShell: rc files sourced on new shell
UserShell->>TUI: openclaw tui (reads $OPENCLAW_GATEWAY_TOKEN)
TUI-->>TUI: gateway authentication proceeds
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Dockerfile`:
- Around line 230-232: The ARG NEMOCLAW_BUILD_ID is declared but never used, so
changing it does not invalidate the token-generation layer; update the
token-generation layer that creates the gateway token (the "token-generation"
RUN/step) to consume NEMOCLAW_BUILD_ID (e.g., reference it in that RUN via ENV
or a no-op echo/printf) so Docker sees the build-arg changes and busts the
cache; ensure you reference ARG NEMOCLAW_BUILD_ID before the token-generation
RUN and use the variable name NEMOCLAW_BUILD_ID in that step so token
regeneration runs on each build-arg change.
In `@scripts/nemoclaw-start.sh`:
- Around line 621-660: The startup currently aborts if writing
${_SANDBOX_HOME}/.bashrc or .profile fails when persisting
OPENCLAW_GATEWAY_TOKEN (snippet using marker_begin/marker_end), which breaks
non-root/sandboxed runs; change the logic to make rc-file writes best-effort by
routing token persistence through the existing /tmp sourced-file pattern (create
a /tmp/openclaw-env-<uid>.sh containing the snippet and ensure rc files source
that file if writable), and if you must directly update ${_SANDBOX_HOME}/.bashrc
or .profile only attempt writes when they are writable and swallow failures (do
not let errors from cat >"$rc_file" or printf >>"$rc_file" abort startup),
leaving the export OPENCLAW_GATEWAY_TOKEN="$token" in the current process
unconditional so gateway startup never depends on rc file writes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 9b2a9d79-dfe8-4da3-93e1-2c11cc9ba0b2
📒 Files selected for processing (6)
.agents/skills/nemoclaw-user-configure-security/references/best-practices.mdDockerfiledocs/security/best-practices.mdscripts/nemoclaw-start.shsrc/lib/onboard.tstest/nemoclaw-start.test.ts
…writes The reverted export_gateway_token code predates the Landlock fix in a54f9a3 and lacks || true guards on .bashrc/.profile writes. Under Landlock enforcement, DAC check ([ -w file ]) passes but the actual write is blocked, crashing the entrypoint under set -e — the exact same failure pattern that caused the 5-day non-root outage. Apply the same || true + continue pattern used in install_configure_guard.
NEMOCLAW_BUILD_ID was declared as an ARG but never referenced by any downstream instruction, so changing it via --build-arg had no effect on Docker layer caching. Reference it on the token-generation RUN line so Docker sees the value change and invalidates the cached layer, ensuring each build produces a fresh gateway auth token. Pre-existing issue surfaced by CodeRabbit review.
…d cache (#2483) ## Summary - Fixes 4x build time regression on Spark (400s+ → ~100s) caused by `NEMOCLAW_BUILD_ID` cache-busting the config generation layer, which invalidated the expensive `openclaw doctor --fix` + `openclaw plugins install` layer on every build - Splits token generation into two steps: config layer writes a placeholder (cacheable), then a late layer injects `secrets.token_hex(32)` (cache-busted but trivially fast) - The doctor/plugins layer no longer rebuilds on every build Depends on #2482 ## Test plan - [x] `npx vitest run --project cli` — 1947 tests pass (ssrf-parity skip is pre-existing, needs plugin build) - [x] All pre-commit and pre-push hooks pass - [ ] Verify build time improvement on Spark <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Optimized Docker image build layers to improve caching efficiency while ensuring unique credentials are generated for each build. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Resolves conflicts in Dockerfile and test/nemoclaw-start.test.ts. - Dockerfile config-generation block: kept the externalized scripts/generate-openclaw-config.py invocation (the PR's purpose) and dropped the inline python3 -c block from main. - Dockerfile token step: dropped the PR's --clear-token step and took main's late-layer secrets.token_hex(32) injection (#2482 reverted gateway auth token externalization, so the token is again baked at build time). - scripts/generate-openclaw-config.py: ported the inference_inputs parsing (#2441) and channel healthMonitor field from main; removed the now-obsolete --clear-token mode. - test/nemoclaw-start.test.ts: took main's version, since the PR's token-externalization regression tests no longer match main's reverted design. - test/generate-openclaw-config.test.ts: removed the --clear-token test cases.
Summary
feat(security): externalize gateway auth token from openclaw.json (#2378))openclaw tuiinside the sandbox — OpenClaw 2026.4.9 requiresOPENCLAW_GATEWAY_TOKENbut the runtime injection fails under Landlock (non-root mode) and the token is no longer inopenclaw.jsonwhere the TUI and gateway can read itopenclaw.jsonso gateways authenticate out-of-the-box againFixes #2480
Test plan
npm run typecheck:clipassesnpx vitest run --project cli— 2110 tests passopenclaw tuiworks inside sandbox after rebuildSummary by CodeRabbit
Documentation
Changes
Tests