fix(cli): redact secret-shaped values in startup args log and apiMachine debug log#1297
Open
YOMXXX wants to merge 1 commit into
Open
fix(cli): redact secret-shaped values in startup args log and apiMachine debug log#1297YOMXXX wants to merge 1 commit into
YOMXXX wants to merge 1 commit into
Conversation
…ine debug log Closes slopus#1279. ## Bug `happy --claude-env ANTHROPIC_TOKEN=sk-…` (or any `--claude-env KEY=VAL` where KEY names a token / API key / secret / auth header) writes the VALUE verbatim into `~/.happy/logs/<timestamp>-pid-*.log`, because the CLI entry point logs `process.argv` unfiltered: packages/happy-cli/src/index.ts:44 logger.debug('Starting happy CLI with args: ', process.argv) The log file is created with the default Node file mode (0o644 in practice), so any local UID can read it. If a user has opted into `DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING`, the same line is forwarded over HTTP to a remote endpoint, exfiltrating the token off the host. This affects any wrapper that injects bearer credentials — proxies, custom Anthropic-compatible endpoints, internal gateways. The same shape also reaches `apiMachine.ts:127`, where the entire `spawn-happy-session` RPC params object — including `token`, `encryptionKey`, `environmentVariables` — is `JSON.stringify`'d into a debug log line. ## Fix New `packages/happy-cli/src/utils/redactSecrets.ts`: - `SECRET_NAME_PATTERN` — case-insensitive substring match for `token / key / secret / auth / password / credential`. - `redactArgvForLog(argv)` — replaces the VALUE half of any `KEY=VAL` arg when KEY matches the pattern. Non-`=`-shaped args pass through unchanged. - `redactObjectForLog(value)` — recursively rewrites the VALUE of any property whose name matches the pattern OR is in the force-redact set (`encryptionKey`, `environmentVariables`). Plain objects + arrays descended into; Date / RegExp / typed-array values returned as-is. Applied at: - `index.ts:44` — wraps the `process.argv` startup log. - `apiMachine.ts:128` — wraps the spawn-session params log. ## Scope - New file: `packages/happy-cli/src/utils/redactSecrets.ts` (~80 LOC). - New test: `redactSecrets.test.ts` — 11 unit tests covering argv redaction (KEY=VAL detection, case-insensitive, empty inputs, values containing `=`), object redaction (top-level, nested, arrays, force-redact list, primitives passthrough, Date/RegExp/ typed-array passthrough). - Two existing files modified to call the helpers. - No API change; no behavior change for users not passing secrets. `pnpm --filter happy typecheck` passes; new redactSecrets test file goes 11/11.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1279.
Bug
`happy --claude-env ANTHROPIC_TOKEN=sk-…` (or any `--claude-env KEY=VAL` where KEY names a token / API key / secret / auth header) writes the VALUE verbatim into `~/.happy/logs/-pid-*.log`, because the CLI entry point logs `process.argv` unfiltered:
```ts
// packages/happy-cli/src/index.ts:44
logger.debug('Starting happy CLI with args: ', process.argv)
```
The log file is created with the default Node file mode (0o644 in practice), so any local UID can read it. If a user has opted into `DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING`, the same line is forwarded over HTTP to a remote endpoint, exfiltrating the token off the host. This affects any wrapper that injects bearer credentials — proxies, custom Anthropic-compatible endpoints, internal gateways.
The same shape also reaches `apiMachine.ts:127`, where the entire `spawn-happy-session` RPC params object — including `token`, `encryptionKey`, `environmentVariables` — is `JSON.stringify`'d into a debug log line. This PR fixes both call sites.
Fix
New `packages/happy-cli/src/utils/redactSecrets.ts`:
Applied at two call sites:
Scope
Test plan
Notes
The redaction pattern is intentionally substring-based, not whole-word — so it catches `ANTHROPIC_TOKEN`, `OAUTH_TOKEN`, `accessToken`, `apiKey`, `SECRET_KEY`, `x-auth-header`, etc. False positives (legitimately non-secret args whose key happens to contain "token" / "key" / etc.) can be added to a future allow-list constant; none observed in the current CLI surface.
Related: there is a class of secret-shaped values that still reach logs from other call sites (e.g. `runCodex.ts`'s token-file write path, various `JSON.stringify` of session metadata). This PR fixes the two highest-impact paths reported in #1279; the same helpers can be applied to the rest in a follow-up audit pass.