-
Notifications
You must be signed in to change notification settings - Fork 2.1k
security: hide API credentials from process argument list #394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| const fs = require("fs"); | ||
| const os = require("os"); | ||
| const path = require("path"); | ||
| const crypto = require("crypto"); | ||
| const { spawn, spawnSync } = require("child_process"); | ||
| const { ROOT, SCRIPTS, run, runCapture, shellQuote } = require("./runner"); | ||
| const { | ||
|
|
@@ -805,13 +806,20 @@ async function setupInference(sandboxName, model, provider) { | |
| step(5, 7, "Setting up inference provider"); | ||
|
|
||
| if (provider === "nvidia-nim") { | ||
| // Create nvidia-nim provider | ||
| run( | ||
| `openshell provider create --name nvidia-nim --type openai ` + | ||
| `--credential ${shellQuote("NVIDIA_API_KEY=" + process.env.NVIDIA_API_KEY)} ` + | ||
| `--config "OPENAI_BASE_URL=https://integrate.api.nvidia.com/v1" 2>&1 || true`, | ||
| { ignoreError: true } | ||
| ); | ||
| // Create nvidia-nim provider — credential written to temp file to avoid | ||
| // exposing the API key in process arguments visible via ps/proc (#325) | ||
| const credPath = path.join(os.tmpdir(), `nemoclaw-cred-${crypto.randomBytes(8).toString("hex")}`); | ||
| fs.writeFileSync(credPath, process.env.NVIDIA_API_KEY, { mode: 0o600, flag: "wx" }); | ||
| try { | ||
| run( | ||
| `openshell provider create --name nvidia-nim --type openai ` + | ||
| `--credential "NVIDIA_API_KEY=$(cat ${shellQuote(credPath)})" ` + | ||
| `--config "OPENAI_BASE_URL=https://integrate.api.nvidia.com/v1" 2>&1 || true`, | ||
|
Comment on lines
+816
to
+817
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Credential still reaches Using 🤖 Prompt for AI Agents |
||
| { ignoreError: true } | ||
| ); | ||
| } finally { | ||
| try { fs.unlinkSync(credPath); } catch {} | ||
| } | ||
| run( | ||
| `openshell inference set --no-verify --provider nvidia-nim --model ${shellQuote(model)} 2>/dev/null || true`, | ||
| { ignoreError: true } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -129,11 +129,18 @@ fi | |||||||||||||||||
| # 3. Providers | ||||||||||||||||||
| info "Setting up inference providers..." | ||||||||||||||||||
|
|
||||||||||||||||||
| # Write API key to temp file to avoid exposing it in process arguments | ||||||||||||||||||
| # visible via ps/proc (#325). The file is cleaned up on exit. | ||||||||||||||||||
| _CRED_FILE=$(mktemp /tmp/nemoclaw-cred-XXXXXX) | ||||||||||||||||||
| chmod 600 "$_CRED_FILE" | ||||||||||||||||||
| printf '%s' "$NVIDIA_API_KEY" > "$_CRED_FILE" | ||||||||||||||||||
| trap 'rm -f "$_CRED_FILE"' EXIT | ||||||||||||||||||
|
Comment on lines
+134
to
+137
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verifies trap is declared before credential write in scripts/setup.sh
trap_line=$(awk '/trap .*_CRED_FILE/ {print NR; exit}' scripts/setup.sh)
write_line=$(awk '/printf .*NVIDIA_API_KEY/ {print NR; exit}' scripts/setup.sh)
echo "trap_line=$trap_line write_line=$write_line"
test -n "$trap_line" -a -n "$write_line" -a "$trap_line" -lt "$write_line"Repository: NVIDIA/NemoClaw Length of output: 87 🏁 Script executed: cat -n scripts/setup.sh | sed -n '130,145p'Repository: NVIDIA/NemoClaw Length of output: 674 🏁 Script executed: head -20 scripts/setup.sh | grep -E "^[[:space:]]*(set|#)" | head -5Repository: NVIDIA/NemoClaw Length of output: 279 🏁 Script executed: head -30 scripts/setup.shRepository: NVIDIA/NemoClaw Length of output: 1047 Install the EXIT trap before any credential write. With Suggested fix_CRED_FILE=$(mktemp /tmp/nemoclaw-cred-XXXXXX)
+trap 'rm -f "${_CRED_FILE:-}"' EXIT
chmod 600 "$_CRED_FILE"
printf '%s' "$NVIDIA_API_KEY" > "$_CRED_FILE"
-trap 'rm -f "$_CRED_FILE"' EXIT📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| # nvidia-nim (build.nvidia.com) | ||||||||||||||||||
| upsert_provider \ | ||||||||||||||||||
| "nvidia-nim" \ | ||||||||||||||||||
| "openai" \ | ||||||||||||||||||
| "NVIDIA_API_KEY=$NVIDIA_API_KEY" \ | ||||||||||||||||||
| "NVIDIA_API_KEY=$(cat "$_CRED_FILE")" \ | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: I couldn’t find any authoritative documentation or source code for a CLI command named If you paste the output of: openshell provider create --help
# and ideally also:
openshell --version
openshell provider --help(or share a link to the repo/docs for this Source
🏁 Script executed: # First, let's examine the setup.sh file around line 143 to see the full context
wc -l scripts/setup.shRepository: NVIDIA/NemoClaw Length of output: 79 🏁 Script executed: # Read the file around line 143 to understand the context
sed -n '130,160p' scripts/setup.shRepository: NVIDIA/NemoClaw Length of output: 1174 🏁 Script executed: # Search for openshell definition and usage in the codebase
rg -i "openshell" --type-list | head -20Repository: NVIDIA/NemoClaw Length of output: 448 🏁 Script executed: # Look for openshell in the repository
fd openshellRepository: NVIDIA/NemoClaw Length of output: 116 🏁 Script executed: # Search for how openshell is invoked or defined
rg "openshell" -A 5 -B 5Repository: NVIDIA/NemoClaw Length of output: 50374 🏁 Script executed: # Find the upsert_provider function definition
rg "upsert_provider\s*\(" -A 10 scripts/setup.sh | head -50Repository: NVIDIA/NemoClaw Length of output: 390 🏁 Script executed: # Search for how openshell provider is invoked
rg "openshell provider" --type sh -A 2 -B 2Repository: NVIDIA/NemoClaw Length of output: 688 🏁 Script executed: # Look for openshell help or documentation within the repo
fd -e md -e txt | xargs grep -l "openshell provider" 2>/dev/null || echo "No docs found"Repository: NVIDIA/NemoClaw Length of output: 72 🏁 Script executed: # Check if there's any help text or documentation in install-openshell.sh
cat scripts/install-openshell.sh | head -100Repository: NVIDIA/NemoClaw Length of output: 2357 🏁 Script executed: # Let's check if there's any reference to openshell --help or version info
rg "openshell.*--help|openshell.*--version" scripts/Repository: NVIDIA/NemoClaw Length of output: 626 🏁 Script executed: # Check if there's any environment variable usage pattern for credentials in the codebase
rg "CREDENTIAL|credential" scripts/ -i -B 2 -A 2 | head -80Repository: NVIDIA/NemoClaw Length of output: 954
The temp file approach protects the parent shell, but the expanded credential value is passed to Investigate whether 🤖 Prompt for AI Agents |
||||||||||||||||||
| "OPENAI_BASE_URL=https://integrate.api.nvidia.com/v1" | ||||||||||||||||||
|
|
||||||||||||||||||
| # vllm-local (if vLLM is installed or running) | ||||||||||||||||||
|
|
||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: NVIDIA/NemoClaw
Length of output: 89
🏁 Script executed:
sed -n '809,825p' bin/lib/onboard.jsRepository: NVIDIA/NemoClaw
Length of output: 918
Move file write inside
try/finallyto guarantee cleanup.If
fs.writeFileSync()throws after the file is created (e.g., due to disk space or permission issues during write), the file will be left behind because thefinallyblock is never reached if thetryblock is never entered.Suggested fix
const credPath = path.join(os.tmpdir(), `nemoclaw-cred-${crypto.randomBytes(8).toString("hex")}`); -fs.writeFileSync(credPath, process.env.NVIDIA_API_KEY, { mode: 0o600, flag: "wx" }); try { + fs.writeFileSync(credPath, process.env.NVIDIA_API_KEY, { mode: 0o600, flag: "wx" }); run( `openshell provider create --name nvidia-nim --type openai ` + `--credential "NVIDIA_API_KEY=$(cat ${shellQuote(credPath)})" ` + `--config "OPENAI_BASE_URL=https://integrate.api.nvidia.com/v1" 2>&1 || true`, { ignoreError: true } ); } finally { try { fs.unlinkSync(credPath); } catch {} }Also applies to: 820-822
🤖 Prompt for AI Agents