fix(desktop): scrub credentials from hermes serve spawn env - #70372
fix(desktop): scrub credentials from hermes serve spawn env#70372zapabob wants to merge 3 commits into
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for targeting a real Desktop secret-forwarding path: current main still forwards process.env into the serve --help probe (apps/desktop/electron/main.ts:1903) and local backend spawns (apps/desktop/electron/main.ts:8096-8110, 8384-8403).
Problems
apps/desktop/electron/scrub-child-env.ts:30classifiesOPENROUTER_BASE_URLas a credential. This is a documented endpoint override (website/docs/reference/environment-variables.md:16) consumed by runtime resolution (hermes_cli/runtime_provider.py:1185), so scrubbing it breaks a supported process-environment configuration.apps/desktop/electron/scrub-child-env.ts:40is case-sensitive. Normalize names before matching so mixed-case credential variables are not forwarded on Windows-supported paths; existing Desktop code already accounts for Windows environment-key casing inapps/desktop/electron/backend-env.ts:25-31.- The member review correctly identifies that #70370 and #70373 add the same helper. Consolidate the shared implementation and the three sets of call sites rather than landing duplicate modules.
Suggested changes
- Retain non-secret endpoint variables, normalize credential-name matching, and add mixed-case coverage.
- Add a composed child-environment test for the backend spawn path after consolidating the sibling work.
Automated hermes-sweeper review.
| 'GEMINI_BASE_URL', | ||
| 'OPENAI_BASE_URL', | ||
| 'OPENROUTER_BASE_URL', | ||
| 'OLLAMA_BASE_URL', |
There was a problem hiding this comment.
OPENROUTER_BASE_URL is a documented, non-secret endpoint override and current provider resolution reads it from the process environment (website/docs/reference/environment-variables.md:16, hermes_cli/runtime_provider.py:1185). Removing it here changes supported Desktop backend configuration; please keep endpoint settings out of the credential denylist.
| return false | ||
| } | ||
|
|
||
| if (CREDENTIAL_NAMES.has(name)) { |
There was a problem hiding this comment.
Normalize name before matching the exact-name set and suffixes. This check currently misses mixed/lower-case credential-shaped keys; the Desktop backend already has Windows-specific case handling for environment keys in backend-env.ts.
|
Bound to the child-process credential-inheritance class under #83565 (#83565) — same bug class, different surface. desktop serve spawn env; Wave F — shares main.ts + scrub-child-env.ts with #70370/#70373: consolidate or strictly sequence, never merge independently. The EPIC carries the live class table, dedup adjudication, and the dependency-driven merge order. |
Desktop child-env consolidation status — 2026-08-18I re-audited #70370, #70372, and #70373 against current Decision: use #70372 as the survivor and consolidate the terminal, serve/backend, updater/bootstrap, and current uninstall child-process sinks into this PR. Strict sequencing would retain the same shared-file conflicts while requiring repeated rebases of The rebuilt history is designed as three logical commits:
The consolidated policy preserves documented non-secret endpoint overrides and the repository's trusted general-AWS runtime contract, matches env names case-insensitively, closes Repository state: no branch rewrite or code push has occurred. The currently connected GitHub integration can read and comment but its Git Data / Contents / Refs writes to Part of #83565. |
|
Follow-up: upstream |
760a371 to
94796a6
Compare
|
Consolidated #70370 and #70373 into this survivor and refreshed it onto official main 5ab7473. Final head: 94796a63a88db9c3ad239fcbb671123d996cea3b. The implementation now follows the current Desktop topology: terminal-ipc.ts, serve --help, primary and pooled backends, four updater hand-offs, both bootstrap script spawns, and uninstall --gui-summary. The shared policy is case-insensitive, scrubs every input map, blocks Apptainer/Singularity effective-name tunnelling, removes FAL_KEY and dynamic Hermes/auxiliary/relay secrets, preserves documented endpoint overrides, the general AWS chain, CLAUDE_CODE_OAUTH_TOKEN, NPM_TOKEN, and empty non-secret values, and re-adds only the freshly minted dashboard token through the dedicated serve builder. Local validation on this rebased head: 17 focused Electron tests passed; Desktop typecheck passed; ESLint and Prettier passed on all five changed files; git diff --check passed. The broader Electron project run reached 1,479 passed / 27 failed / 4 skipped; all 27 failures were unrelated Windows-host assumptions in POSIX mode, symlink, SSH-path, WSL, and temp-directory suites, and none touched these files. Fresh GitHub checks have been triggered for the exact final SHA. |
94796a6 to
e89fc35
Compare
|
Follow-up: official main advanced once more while the prior comment was being posted. I rebased the same validated three-commit series onto 6d85d79 and force-updated with the exact prior-head lease. The current final head is e89fc358714187a0a9320e1364a35239843d7183; the intervening official change only touched Python update files, so the five-file Desktop patch and validation results are unchanged. Fresh checks now target this SHA. |
e89fc35 to
8bb2c17
Compare
|
Follow-up: rebased the consolidated survivor again onto the current official New final head: The intervening official commits do not overlap the five Desktop files in this PR. After the final rebase:
The full Desktop TypeScript check had already passed on the byte-identical Desktop patch immediately before this ancestry-only rebase. Fresh GitHub checks are now running for the new exact head. |
8bb2c17 to
f239561
Compare
|
Rebased onto the frozen official main 8e475ed. Exact remote lease was verified before the update; final head is f2395613582c43de9cb6954b98c0919483952125. The rebase was intended to be semantic-preserving, and the parent ancestry and git diff --check validations passed. Existing focused-test and CI evidence remains in the earlier review comment; GitHub will run fresh checks for this final SHA. |
f239561 to
d95b13a
Compare
Summary
hermes serve/ pool backend children and theserve --helpcapability probe.HERMES_HOME, mintedHERMES_DASHBOARD_SESSION_TOKEN,HERMES_DESKTOP, web dist, ready file, PATH/PYTHONPATH overlays).Why
Long-lived Desktop backends inherited the full parent Electron env, including messaging tokens and provider keys that belong in
HERMES_HOME/.env. Capability probes also do not need secrets.Test plan
npx tsx --test apps/desktop/electron/scrub-child-env.test.ts