Skip to content

Commit 5b32093

Browse files
committed
fix(security): isolate API keys to specific child processes to prevent env pollution
1 parent df47f67 commit 5b32093

File tree

3 files changed

+22
-19
lines changed

3 files changed

+22
-19
lines changed

bin/lib/credentials.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ function prompt(question) {
4444
async function ensureApiKey() {
4545
let key = getCredential("NVIDIA_API_KEY");
4646
if (key) {
47-
process.env.NVIDIA_API_KEY = key;
48-
return;
47+
return key;
4948
}
5049

5150
console.log("");
@@ -67,10 +66,10 @@ async function ensureApiKey() {
6766
}
6867

6968
saveCredential("NVIDIA_API_KEY", key);
70-
process.env.NVIDIA_API_KEY = key;
7169
console.log("");
7270
console.log(" Key saved to ~/.nemoclaw/credentials.json (mode 600)");
7371
console.log("");
72+
return key;
7473
}
7574

7675
function isRepoPrivate(repo) {
@@ -85,15 +84,13 @@ function isRepoPrivate(repo) {
8584
async function ensureGithubToken() {
8685
let token = getCredential("GITHUB_TOKEN");
8786
if (token) {
88-
process.env.GITHUB_TOKEN = token;
89-
return;
87+
return token;
9088
}
9189

9290
try {
9391
token = execSync("gh auth token 2>/dev/null", { encoding: "utf-8" }).trim();
9492
if (token) {
95-
process.env.GITHUB_TOKEN = token;
96-
return;
93+
return token;
9794
}
9895
} catch {}
9996

@@ -114,10 +111,10 @@ async function ensureGithubToken() {
114111
}
115112

116113
saveCredential("GITHUB_TOKEN", token);
117-
process.env.GITHUB_TOKEN = token;
118114
console.log("");
119115
console.log(" Token saved to ~/.nemoclaw/credentials.json (mode 600)");
120116
console.log("");
117+
return token;
121118
}
122119

123120
module.exports = {

bin/lib/onboard.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,9 @@ async function createSandbox(gpu) {
189189
console.log(` Creating sandbox '${sandboxName}' (this takes a few minutes on first run)...`);
190190
const chatUiUrl = process.env.CHAT_UI_URL || 'http://127.0.0.1:18789';
191191
const envArgs = [`CHAT_UI_URL=${chatUiUrl}`];
192-
if (process.env.NVIDIA_API_KEY) {
193-
envArgs.push(`NVIDIA_API_KEY=${process.env.NVIDIA_API_KEY}`);
192+
const nvKey = getCredential("NVIDIA_API_KEY");
193+
if (nvKey) {
194+
envArgs.push(`NVIDIA_API_KEY=${nvKey}`);
194195
}
195196
run(`openshell sandbox create ${createArgs.join(" ")} -- env ${envArgs.join(" ")} nemoclaw-start 2>&1 | awk '/Sandbox allocated/{if(!seen){print;seen=1}next}1'`);
196197

@@ -350,9 +351,10 @@ async function setupInference(sandboxName, model, provider) {
350351

351352
if (provider === "nvidia-nim") {
352353
// Create nvidia-nim provider
354+
const nvKey = getCredential("NVIDIA_API_KEY");
353355
run(
354356
`openshell provider create --name nvidia-nim --type openai ` +
355-
`--credential "NVIDIA_API_KEY=${process.env.NVIDIA_API_KEY}" ` +
357+
`--credential "NVIDIA_API_KEY=${nvKey}" ` +
356358
`--config "OPENAI_BASE_URL=https://integrate.api.nvidia.com/v1" 2>&1 || true`,
357359
{ ignoreError: true }
358360
);

bin/nemoclaw.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ async function setup() {
3838
console.log(" ⚠ `nemoclaw setup` is deprecated. Use `nemoclaw onboard` instead.");
3939
console.log(" Running legacy setup.sh for backwards compatibility...");
4040
console.log("");
41-
await ensureApiKey();
42-
run(`bash "${SCRIPTS}/setup.sh"`);
41+
const key = await ensureApiKey();
42+
run(`bash "${SCRIPTS}/setup.sh"`, { env: { NVIDIA_API_KEY: key } });
4343
}
4444

4545
async function setupSpark() {
46-
await ensureApiKey();
47-
run(`sudo -E NVIDIA_API_KEY="${process.env.NVIDIA_API_KEY}" bash "${SCRIPTS}/setup-spark.sh"`);
46+
const key = await ensureApiKey();
47+
run(`sudo -E bash "${SCRIPTS}/setup-spark.sh"`, { env: { NVIDIA_API_KEY: key } });
4848
}
4949

5050
async function deploy(instanceName) {
@@ -57,10 +57,14 @@ async function deploy(instanceName) {
5757
console.error(" nemoclaw deploy nemoclaw-test");
5858
process.exit(1);
5959
}
60-
await ensureApiKey();
60+
61+
const env = { ...process.env };
62+
env.NVIDIA_API_KEY = await ensureApiKey();
63+
6164
if (isRepoPrivate("NVIDIA/OpenShell")) {
62-
await ensureGithubToken();
65+
env.GITHUB_TOKEN = await ensureGithubToken();
6366
}
67+
6468
const name = instanceName;
6569
const gpu = process.env.NEMOCLAW_GPU || "a2-highgpu-1g:nvidia-tesla-a100:1";
6670

@@ -83,12 +87,12 @@ async function deploy(instanceName) {
8387

8488
if (!exists) {
8589
console.log(` Creating Brev instance '${name}' (${gpu})...`);
86-
run(`brev create ${name} --gpu "${gpu}"`);
90+
run(`brev create ${name} --gpu "${gpu}"`, { env });
8791
} else {
8892
console.log(` Brev instance '${name}' already exists.`);
8993
}
9094

91-
run(`brev refresh`, { ignoreError: true });
95+
run(`brev refresh`, { ignoreError: true, env });
9296

9397
console.log(" Waiting for SSH...");
9498
for (let i = 0; i < 60; i++) {

0 commit comments

Comments
 (0)