fix(security): harden local credential capture#6439
Conversation
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR tightens the local credential helper flow, hardens the checked-in credential form, adds pinning and policy checks, and updates docs and tests for the new capability-gated submit path. ChangesLocal credential helper flow
Estimated code review effort: 5 (Critical) | ~120 minutes Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage remains at 96%, unchanged from the branch. TypeScript / code-coverage/cliThe overall coverage in the branch remains at 76%, unchanged from the branch. Show a code coverage summary of the most impacted files.
Updated |
|
🌿 Preview your docs: https://nvidia-preview-pr-6439.docs.buildwithfern.com/nemoclaw |
E2E Advisor RecommendationRequired E2E: Dispatch hint: Full advisor summaryE2E Recommendation AdvisorBase: Required E2E
Optional E2E
New E2E recommendations
Dispatch hint
|
E2E Target RecommendationRequired E2E targets: Dispatch required E2E targets:
Full E2E target advisor summaryE2E Target AdvisorBase: Required E2E targets
Optional E2E targets
Relevant changed files
|
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
PR Review Advisor (Nemotron Ultra) — BlockedMerge posture: Do not merge until addressed Action checklist
Findings index
🚨 Required before mergeAddress these before merging unless a maintainer explicitly overrides the advisor with rationale.
|
PR Review Advisor — No blocking findingsMerge posture: No blocking advisor findings This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision. |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
test/local-credential-helper.test.ts (1)
300-300: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTest titles are missing the required issue-reference suffix.
None of these titles carry a trailing
(#1234)reference, unlike the siblingtest/starter-prompt-docs.test.ts, which consistently tags its new tests with(#5048)for the same feature. For consistency and traceability, add the local issue reference suffix to each title here too.Also applies to: 309-309, 342-342, 404-404, 494-494, 528-528
🤖 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/local-credential-helper.test.ts` at line 300, Update the affected test titles in local-credential-helper.test.ts so each new case includes the required trailing issue-reference suffix, matching the naming convention used in starter-prompt-docs.test.ts. Specifically, adjust the titles in the test cases around the `rejects $label before listening` and the other referenced `it`/parameterized test declarations so they end with the local issue tag in the same `(`#1234`)` style for consistency and traceability.Source: Coding guidelines
scripts/checks/local-credential-helper-pin.ts (1)
118-138: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtend the parity check to cover the prefix rules.
verifyFieldSafetyRulesonly compares the literal env-name sets, so theLD_,DYLD_, andGIT_CONFIG*branches inisForbiddenChildEnvName/isProcessControlFieldNamecan drift without this guardrail noticing. Consider deriving both checks from one shared source, or compare the full predicate logic instead of just the set contents.🤖 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/checks/local-credential-helper-pin.ts` around lines 118 - 138, The parity check in verifyFieldSafetyRules only compares the extracted env-name sets, so it can miss drift in the prefix-based branches handled by isForbiddenChildEnvName and isProcessControlFieldName. Update the check to validate the full predicate behavior, either by deriving both rules from one shared source or by comparing the complete logic for helper and form instead of only FORBIDDEN_CHILD_ENV_NAMES and PROCESS_CONTROL_FIELD_NAMES. Make sure the new guard covers the LD_, DYLD_, and GIT_CONFIG* cases as well as the literal names.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 `@scripts/local-credential-helper.mts`:
- Around line 444-449: `scrubValues` and `scrubBuffers` only clear object
references, which does not באמת wipe secret data because the values come from
immutable strings created by `JSON.parse` and the serialized body text also
remains in memory. Update the credential capture flow around `scrubValues`,
`scrubBuffers`, and the body parsing path to either keep secrets in `Buffer`
form end-to-end or explicitly document this as a known limitation if a true wipe
is not feasible. If you keep the current approach, avoid implying that
deleting/reassigning parsed string fields is a secure scrub, and rely on the raw
`body.fill(0)` wipe as the only actual memory clearing step.
In `@test/local-credential-helper.test.ts`:
- Around line 1-561: The new test file is tripping the test-conditionals:scan
guardrail because it adds several if statements; reduce or consolidate branching
in local-credential-helper.test.ts, especially in helpers like waitForReadiness,
terminate, request, and captureChild where the new exit-code and body/header
checks were added. Refactor repeated conditional logic into helper functions or
predicate-based expressions where possible, or coordinate a baseline update if
the added branching is truly required for the integration-test behavior.
---
Nitpick comments:
In `@scripts/checks/local-credential-helper-pin.ts`:
- Around line 118-138: The parity check in verifyFieldSafetyRules only compares
the extracted env-name sets, so it can miss drift in the prefix-based branches
handled by isForbiddenChildEnvName and isProcessControlFieldName. Update the
check to validate the full predicate behavior, either by deriving both rules
from one shared source or by comparing the complete logic for helper and form
instead of only FORBIDDEN_CHILD_ENV_NAMES and PROCESS_CONTROL_FIELD_NAMES. Make
sure the new guard covers the LD_, DYLD_, and GIT_CONFIG* cases as well as the
literal names.
In `@test/local-credential-helper.test.ts`:
- Line 300: Update the affected test titles in local-credential-helper.test.ts
so each new case includes the required trailing issue-reference suffix, matching
the naming convention used in starter-prompt-docs.test.ts. Specifically, adjust
the titles in the test cases around the `rejects $label before listening` and
the other referenced `it`/parameterized test declarations so they end with the
local issue tag in the same `(`#1234`)` style for consistency and traceability.
🪄 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: 1650305a-c0da-4c07-b5f8-403989bd732d
📒 Files selected for processing (13)
docs/_components/StarterPrompt.tsxdocs/get-started/quickstart-hermes.mdxdocs/get-started/quickstart-langchain-deepagents-code.mdxdocs/get-started/quickstart.mdxdocs/index.mdxdocs/resources/agent-skills.mdxdocs/resources/local-credential-form.htmlpackage.jsonscripts/checks/local-credential-helper-pin.tsscripts/checks/run.tsscripts/local-credential-helper.mtstest/local-credential-helper.test.tstest/starter-prompt-docs.test.ts
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
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/local-credential-helper.test.ts`:
- Around line 520-550: The Bash hijack test still shells out to curl, which
makes it depend on a host binary unnecessarily. Update the approved command in
the inherited-function test to use a shell builtin such as echo while keeping
the same BASH_FUNC_curl%% and ATTACK_MARKER setup in startHelper, so the
sanitizer path is still exercised without relying on curl being present.
🪄 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: f5da6dcf-82ed-4fb0-bebb-32234844ea66
📒 Files selected for processing (7)
docs/_components/StarterPrompt.tsxdocs/resources/local-credential-form.htmlscripts/checks/local-credential-helper-pin.tsscripts/local-credential-helper.mtstest/local-credential-helper-pin.test.tstest/local-credential-helper.test.tstest/starter-prompt-docs.test.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- docs/_components/StarterPrompt.tsx
- test/local-credential-helper-pin.test.ts
- scripts/checks/local-credential-helper-pin.ts
- docs/resources/local-credential-form.html
- scripts/local-credential-helper.mts
- test/starter-prompt-docs.test.ts
E2E Target Results — ✅ All requested jobs passedRun: 28920925588
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
scripts/checks/local-credential-helper-pin.ts (1)
316-385: 🔒 Security & Privacy | 🔵 TrivialParity check syncs artifacts but doesn't guard against coordinated weakening.
verifyFieldSafetySourceParityensures the canonical, helper, and form copies stay in sync (its stated purpose per the module comment), but a PR that removes an entry fromPROCESS_CONTROL_ENV_NAMES/CREDENTIAL_SHAPED_NAME_PATTERNand mirrors the same removal in the helper/form would still pass this check — there's no independent floor enforcing a minimum required deny-set. This is likely acceptable since human review + the digest pin still gates changes to the reviewed artifacts, but worth being aware of given the check's role as the primary automated safety net here.As per path instructions, "A ratchet must be monotonic and must not be weakenable by the PR it checks."
🤖 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/checks/local-credential-helper-pin.ts` around lines 316 - 385, `verifyFieldSafetySourceParity` only checks that the canonical, helper, and form artifacts match each other, so a coordinated removal can still pass. Add an independent monotonic floor in this check by validating the parsed sets/rules against a fixed required deny-list or pinned baseline for `PROCESS_CONTROL_ENV_NAMES`, `CREDENTIAL_SHAPED_NAME_PATTERN`, and the corresponding helper/form symbols. Keep the existing parity comparisons, but extend the `failures` accumulation so any weakening of the security policy is rejected even when all three copies are edited together.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 `@scripts/checks/local-credential-helper-pin.ts`:
- Around line 316-385: `verifyFieldSafetySourceParity` only checks that the
canonical, helper, and form artifacts match each other, so a coordinated removal
can still pass. Add an independent monotonic floor in this check by validating
the parsed sets/rules against a fixed required deny-list or pinned baseline for
`PROCESS_CONTROL_ENV_NAMES`, `CREDENTIAL_SHAPED_NAME_PATTERN`, and the
corresponding helper/form symbols. Keep the existing parity comparisons, but
extend the `failures` accumulation so any weakening of the security policy is
rejected even when all three copies are edited together.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 044df307-7722-409a-8565-4bc3b8d7f099
📒 Files selected for processing (13)
docs/_components/StarterPrompt.tsxdocs/resources/local-credential-form.htmlscripts/checks/local-credential-helper-pin.tsscripts/local-credential-helper.mtssrc/lib/adapters/http/curl-args.test.tssrc/lib/adapters/http/probe.test.tssrc/lib/security/credential-env.test.tssrc/lib/security/credential-env.tssrc/lib/security/process-control-env.test.tssrc/lib/security/process-control-env.tstest/local-credential-helper-pin.test.tstest/local-credential-helper.test.tstest/starter-prompt-docs.test.ts
✅ Files skipped from review due to trivial changes (1)
- src/lib/security/process-control-env.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- docs/_components/StarterPrompt.tsx
- docs/resources/local-credential-form.html
- test/starter-prompt-docs.test.ts
|
CodeRabbit final-review nitpick acknowledged at current head. No code change is warranted:
The final CodeRabbit review contains no inline findings, and GraphQL reports zero unresolved review threads. |
Review: keep the security helper, but slim the starter promptThanks for the thorough hardening work here. The checked-in, integrity-pinned, one-shot helper is a reasonable answer to a real threat (a coding agent running installers with live secrets, ambient-env hijacking, and agent-generated helper variance). I don't want to lose that. My concern is scope, specifically where this lands in the starter prompt. That prompt is titled "Instructions for a Non-Technical User" and is built around plain language and one-question-at-a-time. The "Handle Tokens Securely and Visually" section roughly doubled and now instructs the agent about execution profiles, Concrete worries:
Suggested direction (decouple, don't delete)
|
|
Following up on my earlier review: I opened a stacked PR that slims the starter-prompt credential section along the lines I suggested, so we can compare side by side.
It keeps the hardened helper, form, and pins from this PR unchanged, and only slims the copy-paste starter prompt: pinned trust boundary + one canonical It's meant as a discussion starter for the UX split, not a required change to this PR. Happy to iterate or fold it in however you prefer. |
<!-- markdownlint-disable MD041 --> ## Summary Stacked on top of #6439. Keeps the hardened credential helper and form from that PR, but slims the copy-paste starter prompt so the default "non-technical user" onboarding path stays easy. The prompt no longer asks the coding agent to synthesize execution-profile prose, per-tool env-strip reasoning, or a `curl | bash` credential wrapper. ## Related Issue Follow-up to #6439. Merge #6439 first, then this on top. ## Changes - Slim the "Handle Tokens Securely and Visually" section of `STARTER_PROMPT` from ~18 dense bullets to 10, keeping the pinned helper/form URLs and SHA-256 digests, one canonical `--execution-profile isolated` recipe, and the core safety rules (verify digests, one-shot confirm-then-run, redacted preview, no secrets in chat or argv, exposure-minimization). - Drop the prose the agent had to assemble itself: the `NPM_CONFIG_*`/`PIP_*` env-strip enumeration, Windows `.cmd` handling, and the `bash -c` non-exported-variable `curl | bash` wrapper. Compress `account-home` to one line and prefer the installer's own secure credential prompt for install-time secrets. - Update `test/starter-prompt-docs.test.ts` to match, and add `not.toContain` regression guards so the wrapper synthesis prose cannot creep back into the copied prompt. The hardened helper still enforces loopback-only access, one-shot submission, absolute executables, and ambient env stripping, so the slimmer prompt keeps the same security posture with far less procedural reasoning for the agent. Helper and form bytes are unchanged, so the pinned digests and commit stay valid. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [x] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [x] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: prompt-only slimming; no change to helper/form bytes or their enforcement, `scripts/checks/local-credential-helper-pin.ts` passes, and this is intended to be reviewed on top of #6439. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification - [x] PR description includes the DCO sign-off declaration and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set — `npx vitest run --project integration test/starter-prompt-docs.test.ts test/local-credential-helper-pin.test.ts` passed 42/42, and `node --experimental-strip-types scripts/checks/local-credential-helper-pin.ts` reported pins immutable and current. - [ ] Applicable broad gate passed — not run; narrow starter-prompt and single-test change covered by the targeted tests and the pin check above. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) — not run; change is prose inside the existing `STARTER_PROMPT` template literal, validated by the TS-AST pin check and starter-prompt tests. - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) --- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
cjagwani
left a comment
There was a problem hiding this comment.
Security blocker at exact head bdf336052f5fbb5b546c20ce7d4140dd859eac89: sanitizeInheritedChildEnvironment is denylist-based and deliberately preserves arbitrary unrecognized ambient variables (the current unit test enshrines this as SAFE_SETTING). That leaves tool-specific execution controls available to the approved child.
A concrete exploit is GIT_TEMPLATE_DIR, which is not rejected. With a submitted credential and an otherwise approved absolute argv such as /usr/bin/git clone <source> <dest>, an ambient GIT_TEMPLATE_DIR can supply an executable hooks/post-checkout; Git runs that hook during clone with the submitted credential in its environment. I reproduced this locally and the hook received the fixture secret. The coding agent controls the helper launch environment, while the user approves argv, so this bypasses the exact-command approval boundary the helper is meant to establish. Similar open-ended controls exist across other toolchains (JAVA_HOME, compiler wrappers/selectors, package-manager homes, and so on), so adding only GIT_TEMPLATE_DIR would not close the class.
Please construct the inherited child environment from a narrow, documented positive allowlist of required non-control OS/locale variables (or from no ambient values), then overlay the execution-profile environment and explicitly approved submitted fields. Any required search path should be reconstructed or explicitly approved rather than inherited. Add an integration regression that launches an approved Git operation with a malicious ambient template hook and proves the hook cannot observe the submitted value. Until then, the stated ambient-env hardening guarantee does not hold.
|
@cv The narrowest fix for the requested-change blocker is to inherit zero ambient entries. Please replace the current |
Signed-off-by: cjagwani <cjagwani@nvidia.com>
Signed-off-by: cjagwani <cjagwani@nvidia.com>
Addressed at e5be9d5: the child now inherits zero ambient entries, and a real Git template-hook regression proves submitted credentials remain unavailable. Independent exact-head review remains required.
|
Maintainer follow-up landed at exact head
Validation: helper suite 122/122; pin/docs suites 42/42; immutable-pin checker passed; CLI build and Node 22 typecheck passed; size budget, changed-file Biome, and diff hygiene passed. Both new commits have good ED25519 signatures. I dismissed my now-addressed change request, but I contributed the fix and will not self-approve. @miyoungc @ericksoa, please review the new exact head independently. |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
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 `@docs/_components/StarterPrompt.tsx`:
- Line 100: Update the helper description in StarterPrompt so it accurately
states that the child process receives no inherited ambient environment at all,
not just that some credential or process-control variables are stripped. Adjust
the wording around the stateless command helper text to reference
sanitizeInheritedChildEnvironment and describe that only the execution-profile
environment plus explicitly submitted fields are provided, keeping the rest of
the behavior unchanged.
🪄 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: 147a3300-60bf-4697-83a0-48ed5e6f2c61
📒 Files selected for processing (7)
docs/_components/StarterPrompt.tsxdocs/get-started/quickstart-langchain-deepagents-code.mdxscripts/local-credential-helper.mtssrc/lib/adapters/http/curl-args.test.tssrc/lib/adapters/http/probe.test.tstest/local-credential-helper.test.tstest/starter-prompt-docs.test.ts
✅ Files skipped from review due to trivial changes (1)
- docs/get-started/quickstart-langchain-deepagents-code.mdx
🚧 Files skipped from review as they are similar to previous changes (3)
- src/lib/adapters/http/curl-args.test.ts
- src/lib/adapters/http/probe.test.ts
- test/starter-prompt-docs.test.ts
| - Form: https://raw.githubusercontent.com/NVIDIA/NemoClaw/dd61a307d7ddf7be99de8ff1e2678fb8ef42f8e6/docs/resources/local-credential-form.html (SHA-256 \`5512a256e0ad7c63a26ab82cf4f5924e98652097172ab8a5dc9d9358dd4f6ae8\`) | ||
| - Treat the two immutable URL and digest pairs as one reviewed trust boundary. Stop if either verification fails; do not substitute another URL, helper, form, or digest. Put fetched copies in a private temporary directory restricted to the current user. | ||
| - The helper requires Node.js 22.16 or newer. If that runtime is unavailable, use a secure local terminal prompt or local app prompt instead; never ask for the value in chat and never fall back to generated code. | ||
| - Run the helper with \`--execution-profile isolated\` for stateless commands. Pass one \`--field NAME:type\` per value, then a literal \`--\` and the exact approved argv. The helper serves a one-time \`http://127.0.0.1\` form, accepts a single submission, then runs that argv; it enforces loopback-only access, requires an absolute executable, and strips ambient credential and process-control variables. Never put credentials in argv. For example: |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Env-hardening wording understates the actual behavior.
The helper now inherits zero ambient environment (sanitizeInheritedChildEnvironment returns {}), so the child receives only the execution-profile environment plus explicitly submitted fields. "strips ambient credential and process-control variables" reads as selective stripping and understates the guarantee this prompt asks non-technical users to trust.
📝 Suggested wording
-it enforces loopback-only access, requires an absolute executable, and strips ambient credential and process-control variables.
+it enforces loopback-only access, requires an absolute executable, and inherits no ambient environment (the child receives only the execution-profile environment and the values I submit).📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - Run the helper with \`--execution-profile isolated\` for stateless commands. Pass one \`--field NAME:type\` per value, then a literal \`--\` and the exact approved argv. The helper serves a one-time \`http://127.0.0.1\` form, accepts a single submission, then runs that argv; it enforces loopback-only access, requires an absolute executable, and strips ambient credential and process-control variables. Never put credentials in argv. For example: | |
| - Run the helper with `--execution-profile isolated` for stateless commands. Pass one `--field NAME:type` per value, then a literal `--` and the exact approved argv. The helper serves a one-time `http://127.0.0.1` form, accepts a single submission, then runs that argv; it enforces loopback-only access, requires an absolute executable, and inherits no ambient environment (the child receives only the execution-profile environment and the values I submit). Never put credentials in argv. For example: |
🤖 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 `@docs/_components/StarterPrompt.tsx` at line 100, Update the helper
description in StarterPrompt so it accurately states that the child process
receives no inherited ambient environment at all, not just that some credential
or process-control variables are stripped. Adjust the wording around the
stateless command helper text to reference sanitizeInheritedChildEnvironment and
describe that only the execution-profile environment plus explicitly submitted
fields are provided, keeping the rest of the behavior unchanged.
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
|
Exact head |
<!-- markdownlint-disable MD041 --> ## Summary Prepares the user documentation for NemoClaw v0.0.78 by replacing the unreleased section with release highlights and synchronizing the affected inference, lifecycle, messaging, and CLI reference pages with merged behavior. ## Changes - Publish the v0.0.78 release-notes section with links to the most specific user guides for each shipped behavior. - Document authoritative Deep Agents route health, Nemotron Ultra profile behavior, and Hermes compatible-endpoint context metadata. - Document forced rebuild recovery after total backup failure and the ownership-safe tunnel/full-stop behavior. - Keep command examples and shared agent variants aligned with the current OpenClaw, Hermes, and Deep Agents interfaces. Source mapping: - [#3787](#3787) -> `docs/about/release-notes.mdx`: Record reliable workspace template seeding during sandbox startup. - [#4960](#4960) -> `docs/about/release-notes.mdx`: Record safer detection of rewritten OpenClaw gateway processes. - [#5676](#5676) -> `docs/about/release-notes.mdx`: Record warning-tolerant agent-list JSON handling. - [#5857](#5857) -> `docs/about/release-notes.mdx`: Record synchronization of explicit OpenClaw main-agent model state. - [#5929](#5929) -> `docs/about/release-notes.mdx`: Record copyable SSH port-forward guidance for remote dashboards. - [#6068](#6068) -> `docs/about/release-notes.mdx`: Record custom-image plugin provenance reconciliation. - [#6116](#6116) -> `docs/about/release-notes.mdx`: Record live-loopback dashboard-forward recovery. - [#6122](#6122) -> `docs/about/release-notes.mdx`: Announce validated, round-trippable policy YAML output. - [#6211](#6211) -> `docs/manage-sandboxes/lifecycle.mdx`, `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain the explicit no-backup `rebuild --force` recovery boundary. - [#6283](#6283) -> `docs/about/release-notes.mdx`: Record Hermes WebUI port alignment. - [#6293](#6293) -> `docs/inference/switch-inference-providers.mdx`, `docs/about/release-notes.mdx`: Document compatible-endpoint context-length probing for Hermes. - [#6320](#6320) -> `docs/about/release-notes.mdx`: Record bounded gateway-recovery waits. - [#6377](#6377) -> `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain rebuild diagnostics and prepared MCP-destroy recovery. - [#6412](#6412) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document authoritative agent-visible inference route health. - [#6421](#6421) -> `docs/about/release-notes.mdx`: Record the longer quiet-pull window for managed vLLM images. - [#6431](#6431) -> `docs/inference/model-capability-audit.mdx`, `docs/about/release-notes.mdx`: Document the version-pinned Nemotron Ultra profile plugin. - [#6439](#6439) -> `docs/about/release-notes.mdx`: Summarize the authenticated, pinned credential-capture helper boundary. - [#6450](#6450) -> `docs/manage-sandboxes/messaging-channels.mdx`, `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document host-forward cleanup and ownership-safe gateway-port release. - [#6474](#6474) -> `docs/manage-sandboxes/messaging-channels.mdx`, `docs/about/release-notes.mdx`: Record composable OpenClaw messaging runtime loaders. - [#6475](#6475) -> `docs/about/release-notes.mdx`: Record removal of the unavailable Kimi K2.6 production endpoint option. - [#6480](#6480) -> `docs/about/release-notes.mdx`: Record stderr routing for the plugin registration banner. - [#6481](#6481) -> `docs/about/release-notes.mdx`: Record post-pull Ollama model discovery checks. - [#6482](#6482) -> `docs/about/release-notes.mdx`: Record Ollama model warm-up after daemon restart. - [#6486](#6486) -> `docs/about/release-notes.mdx`: Publish the opt-in, thread-scoped Deep Agents auto-approval boundary. - [#6490](#6490) -> `docs/about/release-notes.mdx`: Record diagnostics for custom images missing the managed runtime. - [#6494](#6494) -> `docs/inference/model-capability-audit.mdx`, `docs/about/release-notes.mdx`: Document nonempty tool-call content preservation and placeholder rejection. - [#6497](#6497) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document isolated Deep Agents route-probe output. - [#6506](#6506) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document observability-preserving managed route probes. - [#6508](#6508) -> `docs/about/release-notes.mdx`: Link the new extension taxonomy and SDK-readiness reference from the release summary. Release-source verification: GitHub reports all 29 cited source PRs as merged with base `main`, and every merge commit is an ancestor of `origin/main` at `17bf9a6a9688b3b1d69cf4b37d3f23110acb055e`. No source-mapping mismatches were found. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [x] Doc only (includes code sample changes) ## Quality Gates <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: Documentation-only release-prep changes; `npm run docs` validates variants, routes, and Fern content. - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification <!-- Check each applicable item only when supported by the requested evidence. Run targeted tests once per relevant change set and rerun after later edits or hook autofixes that can affect the tested behavior. Do not rerun hook-covered checks. --> - [x] PR description includes the DCO sign-off declaration and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: Tests are not applicable to this documentation-only change set. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) — exited 0 with zero errors; Fern reported the existing unauthenticated redirect-check and light-mode contrast warnings. - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) --- <!-- DCO sign-off is required in this PR description, and every commit must appear as Verified in GitHub. Run: git config user.name && git config user.email --> Signed-off-by: Charan Jagwani <cjagwani@nvidia.com> --------- Signed-off-by: cjagwani <cjagwani@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary This follow-up to NVIDIA#6423 replaces prose-generated credential capture with a checked-in, authenticated one-shot loopback helper and a hardened local form. It binds the reviewed helper/form bytes to immutable commit URLs and SHA-256 digests so coding agents fail closed before collecting secrets. The helper now requires an explicit `isolated` or `account-home` execution profile so stateless commands use private config roots while persistent install/onboard commands use only an explicitly approved absolute working directory and the OS account home. ## Changes - Add a Node.js 22 helper that validates the approved field schema, form digest, loopback request boundary, one-shot capability, and exact child argv without invoking a shell. - Require explicit `isolated` and `account-home` profiles, with private per-session config/temp roots for isolated work and reconstructed account-home roots plus an approved absolute cwd for persistent work. - Deny ambient `NEMOCLAW_*`, `OPENSHELL_*`, config-root, loader, package-manager, container, crypto-provider, and other process-control selectors while permitting only explicitly approved collected fields. - Harden the local form with a no-network preview/edit/confirm flow, redacted summaries, strict response locking, and no retry after an ambiguous submission. - Pin both reviewed artifacts in the starter prompt and add a repository check for digest, package, executable-bit, and helper/form safety-rule parity. - Update user-facing starter-prompt summaries and add integration coverage for malformed requests, races, abandoned responses, CSP, form behavior, and immutable pins. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [x] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [x] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: independent nine-category repository security review completed with final PASS after the CodeQL filesystem-race, CodeRabbit memory-semantics/parity, and GPT-advisor ambient-environment findings were addressed; the helper/form boundary was reviewed for secret handling, input validation, authentication, error behavior, data protection, headers, security tests, and race safety. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification - [x] PR description includes the DCO sign-off declaration and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: `npx vitest run --project integration test/local-credential-helper.test.ts test/local-credential-helper-pin.test.ts test/starter-prompt-docs.test.ts` passed 163/163 tests. - [x] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: `umask 022 && npm test` passed 14,323 tests across 1,267 passing files, with 39 expected skips and 1 todo. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) — not a doc-only PR; the build completed with 0 errors and 2 pre-existing warnings. - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) Advisor-required live E2E: [run 28920925588](https://github.com/NVIDIA/NemoClaw/actions/runs/28920925588) passed credential-sanitization and cloud-onboard at head a413ba3. Additional checks: `npm run checks`, `npm run typecheck:cli`, `npm run source-shape:check`, `npm run test-size:check`, package dry-run contents, post-push raw artifact SHA-256 verification, and `git diff --check` all passed. --- Signed-off-by: Carlos Villela <cvillela@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a stricter “preview then confirm” credential-capture workflow before any credentialed commands are generated or executed. * Improved non-interactive guidance to support secure `curl | bash` execution with approved-command enforcement. * **Bug Fixes** * Hardened the local credential form UI and submission behavior with stronger input validation, loopback-only access, and safer handling of ambiguous/failed outcomes. * **Documentation** * Updated quickstarts and starter prompt text to match the new approve-then-capture flow. * **Tests** * Expanded integration and security tests for the local helper, integrity pinning, and credential/processing policy checks. * **Chores** * Packaged the hardened credential-form asset and added automated integrity verification. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Carlos Villela <cvillela@nvidia.com> Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> Signed-off-by: cjagwani <cjagwani@nvidia.com> Co-authored-by: Miyoung Choi <miyoungc@nvidia.com> Co-authored-by: cjagwani <cjagwani@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Prepares the user documentation for NemoClaw v0.0.78 by replacing the unreleased section with release highlights and synchronizing the affected inference, lifecycle, messaging, and CLI reference pages with merged behavior. ## Changes - Publish the v0.0.78 release-notes section with links to the most specific user guides for each shipped behavior. - Document authoritative Deep Agents route health, Nemotron Ultra profile behavior, and Hermes compatible-endpoint context metadata. - Document forced rebuild recovery after total backup failure and the ownership-safe tunnel/full-stop behavior. - Keep command examples and shared agent variants aligned with the current OpenClaw, Hermes, and Deep Agents interfaces. Source mapping: - [NVIDIA#3787](NVIDIA#3787) -> `docs/about/release-notes.mdx`: Record reliable workspace template seeding during sandbox startup. - [NVIDIA#4960](NVIDIA#4960) -> `docs/about/release-notes.mdx`: Record safer detection of rewritten OpenClaw gateway processes. - [NVIDIA#5676](NVIDIA#5676) -> `docs/about/release-notes.mdx`: Record warning-tolerant agent-list JSON handling. - [NVIDIA#5857](NVIDIA#5857) -> `docs/about/release-notes.mdx`: Record synchronization of explicit OpenClaw main-agent model state. - [NVIDIA#5929](NVIDIA#5929) -> `docs/about/release-notes.mdx`: Record copyable SSH port-forward guidance for remote dashboards. - [NVIDIA#6068](NVIDIA#6068) -> `docs/about/release-notes.mdx`: Record custom-image plugin provenance reconciliation. - [NVIDIA#6116](NVIDIA#6116) -> `docs/about/release-notes.mdx`: Record live-loopback dashboard-forward recovery. - [NVIDIA#6122](NVIDIA#6122) -> `docs/about/release-notes.mdx`: Announce validated, round-trippable policy YAML output. - [NVIDIA#6211](NVIDIA#6211) -> `docs/manage-sandboxes/lifecycle.mdx`, `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain the explicit no-backup `rebuild --force` recovery boundary. - [NVIDIA#6283](NVIDIA#6283) -> `docs/about/release-notes.mdx`: Record Hermes WebUI port alignment. - [NVIDIA#6293](NVIDIA#6293) -> `docs/inference/switch-inference-providers.mdx`, `docs/about/release-notes.mdx`: Document compatible-endpoint context-length probing for Hermes. - [NVIDIA#6320](NVIDIA#6320) -> `docs/about/release-notes.mdx`: Record bounded gateway-recovery waits. - [NVIDIA#6377](NVIDIA#6377) -> `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain rebuild diagnostics and prepared MCP-destroy recovery. - [NVIDIA#6412](NVIDIA#6412) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document authoritative agent-visible inference route health. - [NVIDIA#6421](NVIDIA#6421) -> `docs/about/release-notes.mdx`: Record the longer quiet-pull window for managed vLLM images. - [NVIDIA#6431](NVIDIA#6431) -> `docs/inference/model-capability-audit.mdx`, `docs/about/release-notes.mdx`: Document the version-pinned Nemotron Ultra profile plugin. - [NVIDIA#6439](NVIDIA#6439) -> `docs/about/release-notes.mdx`: Summarize the authenticated, pinned credential-capture helper boundary. - [NVIDIA#6450](NVIDIA#6450) -> `docs/manage-sandboxes/messaging-channels.mdx`, `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document host-forward cleanup and ownership-safe gateway-port release. - [NVIDIA#6474](NVIDIA#6474) -> `docs/manage-sandboxes/messaging-channels.mdx`, `docs/about/release-notes.mdx`: Record composable OpenClaw messaging runtime loaders. - [NVIDIA#6475](NVIDIA#6475) -> `docs/about/release-notes.mdx`: Record removal of the unavailable Kimi K2.6 production endpoint option. - [NVIDIA#6480](NVIDIA#6480) -> `docs/about/release-notes.mdx`: Record stderr routing for the plugin registration banner. - [NVIDIA#6481](NVIDIA#6481) -> `docs/about/release-notes.mdx`: Record post-pull Ollama model discovery checks. - [NVIDIA#6482](NVIDIA#6482) -> `docs/about/release-notes.mdx`: Record Ollama model warm-up after daemon restart. - [NVIDIA#6486](NVIDIA#6486) -> `docs/about/release-notes.mdx`: Publish the opt-in, thread-scoped Deep Agents auto-approval boundary. - [NVIDIA#6490](NVIDIA#6490) -> `docs/about/release-notes.mdx`: Record diagnostics for custom images missing the managed runtime. - [NVIDIA#6494](NVIDIA#6494) -> `docs/inference/model-capability-audit.mdx`, `docs/about/release-notes.mdx`: Document nonempty tool-call content preservation and placeholder rejection. - [NVIDIA#6497](NVIDIA#6497) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document isolated Deep Agents route-probe output. - [NVIDIA#6506](NVIDIA#6506) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document observability-preserving managed route probes. - [NVIDIA#6508](NVIDIA#6508) -> `docs/about/release-notes.mdx`: Link the new extension taxonomy and SDK-readiness reference from the release summary. Release-source verification: GitHub reports all 29 cited source PRs as merged with base `main`, and every merge commit is an ancestor of `origin/main` at `17bf9a6a9688b3b1d69cf4b37d3f23110acb055e`. No source-mapping mismatches were found. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [x] Doc only (includes code sample changes) ## Quality Gates <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: Documentation-only release-prep changes; `npm run docs` validates variants, routes, and Fern content. - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification <!-- Check each applicable item only when supported by the requested evidence. Run targeted tests once per relevant change set and rerun after later edits or hook autofixes that can affect the tested behavior. Do not rerun hook-covered checks. --> - [x] PR description includes the DCO sign-off declaration and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: Tests are not applicable to this documentation-only change set. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) — exited 0 with zero errors; Fern reported the existing unauthenticated redirect-check and light-mode contrast warnings. - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) --- <!-- DCO sign-off is required in this PR description, and every commit must appear as Verified in GitHub. Run: git config user.name && git config user.email --> Signed-off-by: Charan Jagwani <cjagwani@nvidia.com> --------- Signed-off-by: cjagwani <cjagwani@nvidia.com>
Summary
This follow-up to #6423 replaces prose-generated credential capture with a checked-in, authenticated one-shot loopback helper and a hardened local form. It binds the reviewed helper/form bytes to immutable commit URLs and SHA-256 digests so coding agents fail closed before collecting secrets. The helper now requires an explicit
isolatedoraccount-homeexecution profile so stateless commands use private config roots while persistent install/onboard commands use only an explicitly approved absolute working directory and the OS account home.Changes
isolatedandaccount-homeprofiles, with private per-session config/temp roots for isolated work and reconstructed account-home roots plus an approved absolute cwd for persistent work.NEMOCLAW_*,OPENSHELL_*, config-root, loader, package-manager, container, crypto-provider, and other process-control selectors while permitting only explicitly approved collected fields.Type of Change
Quality Gates
Verification
Verifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablenpx vitest run --project integration test/local-credential-helper.test.ts test/local-credential-helper-pin.test.ts test/starter-prompt-docs.test.tspassed 163/163 tests.npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:umask 022 && npm testpassed 14,323 tests across 1,267 passing files, with 39 expected skips and 1 todo.npm run docsbuilds without warnings (doc changes only) — not a doc-only PR; the build completed with 0 errors and 2 pre-existing warnings.Advisor-required live E2E: run 28920925588 passed credential-sanitization and cloud-onboard at head a413ba3.
Additional checks:
npm run checks,npm run typecheck:cli,npm run source-shape:check,npm run test-size:check, package dry-run contents, post-push raw artifact SHA-256 verification, andgit diff --checkall passed.Signed-off-by: Carlos Villela cvillela@nvidia.com
Summary by CodeRabbit
curl | bashexecution with approved-command enforcement.