Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

fix(cli/configure): write .env at mode 0o600 to protect LLM API keys#1969

Closed
ghost wants to merge 1 commit into
mainfrom
unknown repository
Closed

fix(cli/configure): write .env at mode 0o600 to protect LLM API keys#1969
ghost wants to merge 1 commit into
mainfrom
unknown repository

Conversation

@ghost

@ghost ghost commented May 19, 2026

Copy link
Copy Markdown

Summary

The configure subcommand at packages/cli/src/configure.ts:186 prompts the user for their LLM provider API keys and patches them into a .env file via writeFile(filePath, updatedLines.join(" "), "utf-8") with no mode argument. On macOS and most Linux defaults (umask 022) the file lands at 0o644 — world-readable. Any local account or process that can traverse the working directory can recover the keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, AZURE_OPENAI_API_KEY, etc.) and use them under the user's account quota.

This PR adds { mode: 0o600 } to the writeFile call (applies on file creation) plus a follow-up chmod(filePath, 0o600) (wrapped in try/catch for Windows) so pre-existing .env files at 0o644 converge to 0o600 on the next save.

Files changed

  • packages/cli/src/configure.ts — added chmod to the fs/promises import, passed { encoding: "utf-8", mode: 0o600 } to writeFile, added a follow-up chmod.

Verification

import { writeFile } from "fs/promises";
import { statSync } from "fs";

await writeFile("/tmp/genai-test.env", "OPENAI_API_KEY=sk-...
");
console.log((statSync("/tmp/genai-test.env").mode & 0o777).toString(8));  // 644 on default umask 022

After the PR: 600.

Context

Same CWE-732 finding class as huggingface/huggingface_hub#4234 (merged-approved), prisma/prisma#29568, eosphoros-ai/DB-GPT#3077, cline/cline#10893, replicate/cli#111, musistudio/claude-code-router#1399, anthropics/claude-cookbooks#642 filed today across the AI-tooling ecosystem. Industry baseline (GitHub CLI / AWS CLI / Google Cloud SDK / Stripe CLI / Pulumi) is 0o600 for credential files.

The `configure` subcommand prompts the user for their LLM provider API
keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, AZURE_OPENAI_API_KEY, etc.) and
patches them into the `.env` file via `writeFile(filePath, content, "utf-8")`
with no `mode` option. On macOS and most Linux defaults (umask 022) that
lands the file at 0o644 — world-readable. Any local account or process
that can traverse the home / working directory can recover the keys and
use them under the user's account quota.

This commit:
- Adds `chmod` to the `fs/promises` import.
- Passes `{ encoding: "utf-8", mode: 0o600 }` to `writeFile` so a freshly-
  created `.env` is atomically restricted to the user.
- Adds a follow-up `await chmod(filePath, 0o600)` (wrapped in try/catch
  for Windows) so overwrites of a pre-existing `.env` at 0o644 converge
  to 0o600 on the next save.

Mirrors industry-baseline credential-file handling (GitHub CLI's
~/.config/gh/hosts.yml, AWS CLI's ~/.aws/credentials at 0o600).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ghost

ghost commented May 20, 2026

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@ghost ghost closed this by deleting the head repository Jun 26, 2026
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants