Skip to content

fix(sandbox): reconcile readonly gateway-token trust anchor on source - #8432

Open
yanyunl1991 wants to merge 19 commits into
mainfrom
fix/proxy-env-token-conflict-8428
Open

fix(sandbox): reconcile readonly gateway-token trust anchor on source#8432
yanyunl1991 wants to merge 19 commits into
mainfrom
fix/proxy-env-token-conflict-8428

Conversation

@yanyunl1991

@yanyunl1991 yanyunl1991 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

The generated /tmp/nemoclaw-proxy-env.sh assigned OPENCLAW_GATEWAY_TOKEN directly, so sourcing it aborted with the shell's raw readonly error (exit 2) when the sourcing shell had already pinned the variable readonly to a conflicting value. This PR reconciles the token against any pre-existing value and emits a controlled conflict diagnostic instead.

Closes #8428.

Reproduction

On a connected OpenClaw sandbox:

sh -c 'readonly OPENCLAW_GATEWAY_TOKEN=SENTINEL_CONFLICT; . /tmp/nemoclaw-proxy-env.sh'

Environment

  • Test machine: our Ubuntu 24.04 x86_64 test host (no GPU)
  • NemoClaw main revision 26bd9f5ce, Node v22.22.2, dash /bin/sh
  • Fresh OpenClaw sandbox (Local Ollama provider)

Observed on main (before fix)

exit=2
sh: 604: /tmp/nemoclaw-proxy-env.sh: OPENCLAW_GATEWAY_TOKEN: is read only

Observed on fix/... (after fix)

exit=1
Error: conflicting trust anchor

(The trusted token is not echoed. A normal source with no pre-existing pin still sets the token and exits 0.)

Analysis

write_runtime_shell_env() in scripts/nemoclaw-start.sh emits the token block into the proxy-env file as a case on OPENCLAW_GATEWAY_URL whose arms assigned OPENCLAW_GATEWAY_TOKEN=... directly (the loopback arm was line 604 in the generated file). A plain variable assignment to a variable that the sourcing shell has already made readonly is a fatal error in POSIX sh (dash): sourcing aborts with exit 2 and the shell's own is read only message, so NemoClaw's intended controlled diagnostic never runs, and the raw failing assignment line is surfaced. The proxy-env file is the trust anchor for OPENCLAW_GATEWAY_TOKEN; an externally pinned, conflicting value should be reported as a conflict, not crash sourcing.

Fix

Each URL-case arm now embeds its intended value directly and reconciles it against the caller's existing OPENCLAW_GATEWAY_TOKEN:

  • Probe writability in a subshell so a readonly pin cannot abort sourcing. If writable, advance the anchor on fresh and repeated sources.
  • If the current readonly value already matches, leave it unchanged.
  • Otherwise emit Error: conflicting trust anchor and return 1 without echoing the trusted token.

The emitted file uses no caller-visible temporary variable, so a caller cannot predeclare the helper name as readonly and interfere with reconciliation. Scope remains limited to OPENCLAW_GATEWAY_TOKEN; non-secret routing variables are unchanged.

Changes

  • scripts/nemoclaw-start.sh: emit collision-resistant reconciliation in every gateway URL branch.
  • test/proxy-env-gateway-token-conflict.test.ts: source the generated proxy environment under POSIX sh and Bash, including conflicting and matching readonly values, writable repeated sourcing, helper-name collision, and remote empty-token behavior.
  • Existing startup and service-environment assertions now match the emitted direct assignments, and the test-size ratchet tracks the smaller startup test file.

Type of Change

  • Code change (feature, bug fix, or refactor)

Verification

  • 55 focused tests passed with one expected skip across gateway-token, startup, and service-environment coverage.
  • CLI build and type-check passed.
  • Repository pre-commit checks passed on all changed files, including Biome, shfmt, ShellCheck, secret scanning, repository checks, source-shape, and test-size budgets.
  • GitHub recognizes the maintainer follow-up commit as Verified and its DCO sign-off is present.
  • Documentation writer review returned no-docs-needed.
  • Security review found no credential disclosure, injection, authorization, dependency, cryptography, configuration, or holistic posture regression.

AI Disclosure

  • AI-assisted — tool: Claude Code

Signed-off-by: Yanyun Liao yanyunl@nvidia.com

Summary by CodeRabbit

  • Bug Fixes

    • Improved gateway token handling for proxy environments.
    • Prevented token exposure for URLs with embedded credentials or non-local destinations.
    • Added safe handling for existing read-only token settings, including clear conflict errors.
    • Ensured gateway tokens remain available across startup and service configurations.
  • Tests

    • Added regression coverage for conflicting, matching, empty, read-only, and writable token configurations.
    • Verified consistent behavior when sourcing generated environments with both supported shells.

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: Independent review confirmed this change only hardens internal gateway-token reconciliation, existing security and sandbox-hardening docs remain accurate, and the docs build passes with no errors.
  • Agent: Codex documentation writer subagent

The generated /tmp/nemoclaw-proxy-env.sh assigned OPENCLAW_GATEWAY_TOKEN
directly. When a sourcing shell had already pinned the variable readonly to
a conflicting value, the assignment aborted sourcing with the shell's raw
readonly error (exit 2, "OPENCLAW_GATEWAY_TOKEN: is read only") — leaking the
failing assignment line and bypassing NemoClaw's controlled diagnostic.

Resolve the intended token into a temp variable per URL case, then reconcile
it against any pre-existing value: probe writability in a subshell (so a
readonly pin can never abort sourcing), advance the anchor when writable,
stay silent when it already holds the intended value, and otherwise emit a
controlled "Error: conflicting trust anchor" diagnostic (exit 1) that never
echoes the trusted token. Scoped to the gateway token, the secret trust
anchor named in the report; the non-secret routing vars are left unchanged.

Fixes #8428

Signed-off-by: Yanyun Liao <yanyunl@nvidia.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The proxy environment now stages URL-specific gateway token values before reconciliation. It handles writable, matching readonly, conflicting readonly, and remote empty-token states without exposing the trusted token. Tests cover POSIX shell and Bash behavior.

Changes

Gateway token reconciliation

Layer / File(s) Summary
Generate and reconcile gateway tokens
scripts/nemoclaw-start.sh
The script computes an intended token for each URL branch. The reconciliation helper updates writable values, preserves matching readonly values, and reports conflicting readonly values without printing the token.
Validate readonly conflict handling
test/proxy-env-gateway-token-conflict.test.ts
The tests execute the generated shell in isolated POSIX shell and Bash environments. They verify readonly conflicts, matching anchors, repeated sourcing, private-variable handling, and remote empty tokens.
Update runtime environment validation
test/service-env.test.ts, test/nemoclaw-start.test.ts, ci/test-file-size-budget.json
Runtime tests source the generated file with both shells and verify the exported token and absence of _nemoclaw_gateway_token. The import order and file-size budget are updated.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: area: security, security

Suggested reviewers: apurvvkumaria, prekshivyas

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement controlled conflict handling with exit code 1, the required diagnostic, token redaction, and POSIX sh and Bash regression coverage for issue [#8428].
Out of Scope Changes check ✅ Passed The implementation, regression tests, import reorder, and test-budget update directly support the gateway-token reconciliation fix and its validation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes reconciling the readonly gateway-token trust anchor during sourcing.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/proxy-env-token-conflict-8428

Comment @coderabbitai help to get the list of available commands.

@github-code-quality

github-code-quality Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 415bf54 in the fix/proxy-env-token-... branch remains at 96%, unchanged from commit c31724f in the main branch.


Updated August 07, 2026 11:14 UTC

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/nemoclaw-start.sh (1)

4077-4088: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the intended token out of caller scope.

If _nemoclaw_intended_gateway_token is readonly, the URL-case assignment emits a raw readonly diagnostic before reconciliation. With set -e, sourcing exits before the controlled path. Without set -e, reconciliation can replace the gateway token with the caller's value. Generate reconciliation branches with the escaped token literal directly, and add a readonly-variable regression case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/nemoclaw-start.sh` around lines 4077 - 4088, Avoid assigning to
_nemoclaw_intended_gateway_token in the OPENCLAW_GATEWAY_URL case; generate
reconciliation branches using the escaped token literal directly so readonly
caller variables cannot trigger diagnostics or override the intended token. Add
a regression case covering a readonly _nemoclaw_intended_gateway_token under
both controlled execution paths.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/proxy-env-gateway-token-conflict.test.ts`:
- Around line 105-111: Update the test named “advances a writable pre-existing
value (repeated non-readonly source)” to use a writable preset sentinel
different from REAL_TOKEN, source the intended-token setup and reconcile block
twice within the same shell, and assert through the existing runReconcile public
boundary that both executions succeed and retain REAL_TOKEN.
- Around line 61-63: Parameterize the shell executable used by the test’s
spawnSync invocation, replacing the hardcoded sh command in the runReconcile
test flow. Execute both the conflict and matching-readonly scenarios under POSIX
sh and Bash, while asserting behavior through the public runReconcile boundary.

---

Outside diff comments:
In `@scripts/nemoclaw-start.sh`:
- Around line 4077-4088: Avoid assigning to _nemoclaw_intended_gateway_token in
the OPENCLAW_GATEWAY_URL case; generate reconciliation branches using the
escaped token literal directly so readonly caller variables cannot trigger
diagnostics or override the intended token. Add a regression case covering a
readonly _nemoclaw_intended_gateway_token under both controlled execution paths.
🪄 Autofix

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: cde02906-c000-41e6-be30-622da20117a8

📥 Commits

Reviewing files that changed from the base of the PR and between bf429e9 and 5bb9090.

📒 Files selected for processing (2)
  • scripts/nemoclaw-start.sh
  • test/proxy-env-gateway-token-conflict.test.ts

Comment thread test/proxy-env-gateway-token-conflict.test.ts Outdated
Comment thread test/proxy-env-gateway-token-conflict.test.ts Outdated
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 1 warning · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Failed

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

2 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — trust anchor at scripts/nemoclaw-start.sh:3396: Retain `trust anchor`; repository usage already names an authoritative integrity or configuration value with this term.
  • established — reconcile at scripts/nemoclaw-start.sh:4102: Retain `reconcile`; it matches the controlled definition for bringing observed state into agreement with desired state.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite against this exact revision.

Recommended E2E: managed-image-multiarch-startup

1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Cover readonly conflicts in remote token-clearing branches

  • Location: test/proxy-env-gateway-token-conflict.test.ts:181
  • Category: tests
  • Problem: The remote-URL test verifies that a writable token becomes empty, but it does not exercise the changed reconciliation path when a nonempty token is readonly. The same emitted helper now handles remote and credential-bearing URL branches, so a readonly conflicting token could regress to a shell abort or an unintended success without this test detecting it.
  • Impact: A regression in an empty-token branch can leave an untrusted readonly token in effect, abort sourcing with a shell diagnostic, or bypass the intended controlled failure without focused coverage.
  • Recommendation: Add a parameterized sh/Bash test that presets a readonly nonempty token and sources generated output for `wss://remote.example.test` and a credential-bearing URL; assert status 1, the controlled diagnostic, no readonly-shell diagnostic, and no token output.
  • Verification: Inspect the generated remote and credential-bearing case arms in scripts/nemoclaw-start.sh:4108-4127 and run the focused Vitest file after adding the readonly-empty-token scenarios.
  • Test coverage: Source the generated proxy environment under sh and Bash with a remote or credential-bearing `OPENCLAW_GATEWAY_URL` and readonly `OPENCLAW_GATEWAY_TOKEN=SENTINEL_CONFLICT`; assert exit status 1, `Error: conflicting trust anchor`, no raw readonly error, and no token output.
  • Evidence: scripts/nemoclaw-start.sh:4112 and 4125 emit the reconciliation helper with an intended empty token for credential-bearing and other remote URL cases. test/proxy-env-gateway-token-conflict.test.ts:181-188 verifies only a writable remote URL path.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

The gateway-token trust-anchor reconcile now resolves the token into
`_nemoclaw_intended_gateway_token` before assigning OPENCLAW_GATEWAY_TOKEN,
so the emitted proxy-env file embeds the token value on that temp variable.
Point the existing generator golden-output assertions at the new embedding
site; behavioral coverage (sourcing sets OPENCLAW_GATEWAY_TOKEN) is unchanged.

Refs #8428

Signed-off-by: Yanyun Liao <yanyunl@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/nemoclaw-start.test.ts (1)

4784-4794: 🎯 Functional Correctness | 🔵 Trivial | 🏗️ Heavy lift

Validate the generated environment through its public shell behavior.

The changed assertions rely on the private _nemoclaw_intended_gateway_token assignment. They can pass while sourcing exports a stale token or leaves the temporary variable set. Test the generated file in isolated POSIX sh and Bash instead.

  • test/nemoclaw-start.test.ts#L4784-L4794: assert that sourced OPENCLAW_GATEWAY_TOKEN equals updatedConfig.gateway.auth.token; do not check only that the export statement exists.
  • test/nemoclaw-start.test.ts#L665-L665: validate the escaped token after sourcing.
  • test/nemoclaw-start.test.ts#L684-L684: validate the runtime token value.
  • test/nemoclaw-start.test.ts#L697-L697: retain ordering checks only if they protect behavior not observable after sourcing.
  • test/nemoclaw-start.test.ts#L715-L717: validate the generated token through the exported environment.
  • test/nemoclaw-start.test.ts#L735-L737: validate the rotated token through the exported environment.
  • test/nemoclaw-start.test.ts#L764-L766: validate the JSON5 rotation result through the exported environment.
  • test/service-env.test.ts#L665-L665: assert the exported OPENCLAW_GATEWAY_TOKEN value and temporary-variable cleanup.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/nemoclaw-start.test.ts` around lines 4784 - 4794, Replace private
temporary-variable assertions with isolated POSIX sh and Bash sourcing checks:
in test/nemoclaw-start.test.ts lines 4784-4794, assert sourced
OPENCLAW_GATEWAY_TOKEN equals updatedConfig.gateway.auth.token and verify
temporary-variable cleanup; lines 665, 684, 715-717, 735-737, and 764-766 must
validate escaped, runtime, generated, rotated, and JSON5-rotated tokens through
the exported environment; retain lines 697 only for ordering behavior not
observable after sourcing. In test/service-env.test.ts line 665, assert the
exported token value and temporary-variable cleanup.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/nemoclaw-start.test.ts`:
- Around line 4784-4794: Replace private temporary-variable assertions with
isolated POSIX sh and Bash sourcing checks: in test/nemoclaw-start.test.ts lines
4784-4794, assert sourced OPENCLAW_GATEWAY_TOKEN equals
updatedConfig.gateway.auth.token and verify temporary-variable cleanup; lines
665, 684, 715-717, 735-737, and 764-766 must validate escaped, runtime,
generated, rotated, and JSON5-rotated tokens through the exported environment;
retain lines 697 only for ordering behavior not observable after sourcing. In
test/service-env.test.ts line 665, assert the exported token value and
temporary-variable cleanup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a9a48070-5887-49b8-bbe0-90374723d3e1

📥 Commits

Reviewing files that changed from the base of the PR and between 5bb9090 and bda0025.

📒 Files selected for processing (2)
  • test/nemoclaw-start.test.ts
  • test/service-env.test.ts

Rename the reconcile temp variable to `_nemoclaw_gateway_token`. The longer
prior name pushed the golden-output assertions in test/nemoclaw-start.test.ts
past the 100-column width, so Biome wrapped them and grew the file past its
legacy test-file-size budget. The shorter name keeps those assertions on one
line and the file at its budget. No behavior change.

Refs #8428

Signed-off-by: Yanyun Liao <yanyunl@nvidia.com>
@yanyunl1991

Copy link
Copy Markdown
Contributor Author

Note on CI status: the current red is not from this PR. build-typecheck is failing on main itself because src/lib/inference/serving/resolver.ts has a duplicate readinessComparisonMatches implementation (TS2393), which cascades into every downstream job (cli-test-shards, installer-integration, E2E, etc.). Tracked in #8438.

This branch touches only scripts/nemoclaw-start.sh and its tests (zero diff to resolver.ts). With the duplicate removed locally on top of latest main, build:cli/typecheck:cli are clean and this PR's tests pass. I'll merge latest main and re-run once #8438 is resolved.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/proxy-env-gateway-token-conflict.test.ts`:
- Around line 126-135: Update the repeated-source test using the existing SHELLS
parameterization, invoking runReconcile with each shell value. Keep the current
assertions for successful reconciliation, twice-emitted REAL_TOKEN output, and
empty stderr so the observable behavior is verified under both POSIX sh and
Bash.
🪄 Autofix

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: 725564e8-5be0-414e-835d-56f96ca1a813

📥 Commits

Reviewing files that changed from the base of the PR and between 46d089e and e91c296.

📒 Files selected for processing (5)
  • ci/test-file-size-budget.json
  • scripts/nemoclaw-start.sh
  • test/nemoclaw-start.test.ts
  • test/proxy-env-gateway-token-conflict.test.ts
  • test/service-env.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/service-env.test.ts
  • scripts/nemoclaw-start.sh

Comment thread test/proxy-env-gateway-token-conflict.test.ts Outdated
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

The codebase-growth failure was PR-caused: the focused regression introduced one conditional solely to propagate generator failure. The regression is now linear with zero conditional statements. The focused contract passes 7/7, the repository conditional scan no longer reports this file, the test-size budget passes, and the published follow-up is signed, DCO-compliant, and Verified.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

CI classification update: every required check is green for the current branch revision.

The non-required managed runtime lane invokes the removed test/e2e/live/managed-image-activation-e2e.test.ts file, so Vitest exits before exercising this PR. That obsolete PR gate was removed by #8445. This is a retired-workflow failure, not a failure of the gateway-token reconciliation changes, and I will not rerun it unchanged.

The PR-specific Bash contract, focused tests, repository gates, DCO, commit verification, documentation review, security review, and required CI pass. All actionable review threads are resolved. The remaining merge gate is independent maintainer approval.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Maintainer follow-up complete:

  • Review Advisor PRA-1: addressed. The readonly equality now uses POSIX case syntax, so a Bash caller cannot override the comparison by shadowing the test command. A focused regression covers that attack and verifies fail-closed behavior without token disclosure.
  • Current main refresh: included. This restores the managed-activation test file that was absent when the prior all-agent lane stopped before running tests.
  • Validation: 161 passed, 1 expected skip across proxy-env, startup, and service-env coverage; focused contract 9/9; CLI type-check, full repository diff checks, shfmt, ShellCheck, source-shape, test-size, and docs build passed.
  • Documentation: independent writer review PASS, no docs change needed.
  • Security: PASS across secrets, input handling, authorization, dependencies, logging, cryptography, configuration, security tests, and holistic posture. No findings.
  • Compliance: new maintainer commits are signed and DCO-compliant. Fresh GitHub verification and CI/review are running.

The PR still requires independent approval before merge.

@github-actions github-actions Bot added v0.0.105 Release target and removed v0.0.104 labels Aug 7, 2026
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Security follow-up complete:

  • The branch previously used shadowable return/exit commands to propagate a readonly-token conflict. A Bash caller could override that status path, keep a conflicting token, and make sourcing report success.
  • The generated environment now writes the static diagnostic through /usr/bin/printf and fails through /usr/bin/false, so caller-defined shell functions cannot neutralize the conflict result.
  • A focused Bash regression shadows return, exit, and echo and proves status 1, the controlled diagnostic, and no trusted-token disclosure.

Validation passed: focused security contract 10/10; service-environment coverage 38/38 with one platform-specific skip; gateway-token suite 9/9; CLI type-check; ShellCheck; shfmt; source-shape, test-size, test-title, secret-scan, and repository policy checks. The signed follow-up is in commit 1beda0b.

Fresh CI and automated review are running. Independent maintainer approval remains required because this branch contains substantive maintainer-authored fixes.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Test receipt refinement: commit 1ae9214 makes the regression capture the sourced file's status directly, without relying on shell errexit. The test uses reserved case syntax and absolute status commands, so the caller-defined return/exit functions under test cannot influence the assertion. The focused contract remains 10/10, normal hooks and pre-push type-check passed, and fresh CI is running.

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Security review

Verdict

PASS. The validated branch revision 1ae9214 is safe to advance. The review found one status-propagation bypass during this pass; commits 1beda0b and 1ae9214 remediate it and add direct regression proof. No security findings remain.

Findings

No open findings.

Nine-category review

  1. Secrets and credentials — PASS. The trusted gateway token remains shell-escaped, is never included in the conflict diagnostic, and the negative tests assert that it is absent from stdout and stderr.
  2. Input validation and sanitization — PASS. The existing loopback URL allowlist and single-quoted token emission remain intact. Explicit non-loopback and user-info URL forms still receive an empty token.
  3. Authentication and authorization — PASS. The change does not broaden gateway access. A conflicting readonly token fails closed instead of remaining usable after a caller-defined shell function neutralizes the status path.
  4. Dependencies — PASS. No dependency or package changes.
  5. Error handling and logging — PASS. The conflict path emits one static diagnostic through /usr/bin/printf, returns status 1 through /usr/bin/false, and does not expose the trusted value or a raw readonly-assignment line.
  6. Cryptography and data protection — PASS. No cryptographic behavior changes. Token confidentiality is preserved.
  7. Configuration and secure defaults — PASS. Proxy-environment ownership and permissions are unchanged. The status path uses immutable system executables already required by the shipped runtime.
  8. Security testing — PASS. Coverage exercises POSIX sh and Bash, matching and conflicting readonly values, writable repeated sourcing, a readonly helper-name collision, remote empty-token behavior, a shadowed test command, and shadowed return/exit/echo functions. The latter test captures the source operation's status directly.
  9. Holistic posture — PASS. The implementation removes a fail-open shell-function boundary without expanding privileges, network reach, configuration mutability, or credential exposure.

Files reviewed: ci/test-file-size-budget.json, scripts/nemoclaw-start.sh, test/nemoclaw-start.test.ts, test/proxy-env-gateway-token-conflict.test.ts, and test/service-env.test.ts.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Maintainer refresh and CI disposition for branch revision 150b05d2d75b:

  • The branch was behind current main. Its managed-runtime activation failure matched the shared Docker normalization regression already corrected by feat(inference): activate managed llama.cpp on DGX Spark #8448. I merged current main cleanly with no conflict, and the effective PR diff remains limited to the same five gateway-token hardening and test-budget files.
  • The CLI shard failure was a timeout in the unchanged preflight unit suite. After the refresh, the full preflight and managed Docker normalization suites pass 144/144 locally in 3.18 seconds.
  • The PR-focused startup, proxy-env conflict, and service-env suites pass 162 tests with one intentional platform skip. CLI type-checking and precise Vitest project membership also pass.
  • The independent documentation writer rechecked the final change set and returned no-docs-needed; existing gateway-token and proxy-env security documentation remains accurate, and the docs build passes with no errors.
  • The nine-category security disposition remains PASS. The change fails closed when caller-defined Bash functions shadow trusted status commands, preserves the readonly gateway-token trust anchor, adds no credential source or exposure, changes no authorization/dependency/cryptography/network-policy boundary, and exercises the hostile-function paths through the sourced public boundary.
  • The refresh commit is signed, GitHub Verified, and DCO-compliant. All review threads remain resolved.

Fresh repository checks and automated review are running. Independent approval remains required; no gate is waived and no merge was attempted.

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Fresh validation completed after the current-main refresh: 45 checks pass, five are intentionally skipped, and no check is failed or pending. The live all-agent managed-runtime activation gate now passes, as do all CLI shards, security scans, documentation review, automated review, DCO, and integrity gates. All review threads remain resolved. Independent approval is the only remaining gate; no merge or bypass was attempted.

cv
cv previously requested changes Aug 7, 2026

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refresh this branch onto the current main commit and rerun the required checks. The current base SHA is df56c02b, while main is cc4b816c; repository policy does not permit approval of stale trust-anchor code. I reviewed token confidentiality, readonly conflict handling, URL branches, repeated sourcing, command-shadowing cases, POSIX sh and Bash evidence, and fail-closed status propagation and found no additional defect.

@yanyunl1991
yanyunl1991 requested a review from cv August 7, 2026 09:40
@cv
cv dismissed their stale review August 7, 2026 10:31

The branch refresh addresses the stale-base request, and the current trust-anchor diff remains reviewed. Required checks remain separate.

@copy-pr-bot

copy-pr-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression release-target v0.0.105 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Ubuntu 24.04][CLI&UX] readonly gateway token conflict returns shell error instead of controlled diagnostic

3 participants