← Back to PRs

#10258: fix(config): preserve ${ENV_VAR} references when writing config (#9813)

by nu-gui open 2026-02-06 08:23 View on GitHub →
stale
## Summary - When the gateway rewrites `openclaw.json`, `${ENV_VAR}` template references were expanded to their actual secret values, leaking credentials into a file that could be committed to git - Add `collectConfigEnvRefs()` to capture `${VAR}` template locations from the on-disk config before expansion - Add `restoreConfigEnvVarRefs()` to restore the original template strings when writing back - Integrate into `writeConfigFile()` so env var references are preserved through read-modify-write cycles Fixes #9813 ## Test plan - [x] 17 new unit tests for `collectConfigEnvRefs` and `restoreConfigEnvVarRefs` - [x] Tests cover: flat/nested/array structures, inline vars, changed values, full roundtrip - [x] All 43 tests pass (26 original + 17 new) - [x] `pnpm check` passes (0 warnings, 0 errors) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> - Adds env-var reference tracking/restoration (`collectConfigEnvRefs`, `restoreConfigEnvVarRefs`) so `${ENV_VAR}` templates survive read/modify/write cycles instead of being persisted as secrets. - Integrates the preservation step into `writeConfigFile()` by re-reading the on-disk config (with `$include` resolution) and restoring matching templates before JSON serialization. - Extends unit tests to cover collection/restoration across flat/nested/array structures and inline `${VAR}` usage. <h3>Confidence Score: 2/5</h3> - This PR should not be merged until the env-ref preservation logic is made reliable under repeated calls and failure scenarios. - Core idea is sound and tests cover basic roundtrips, but the current implementation has a stateful global-regex bug that can miss `${VAR}` refs, and the write path silently falls back to writing expanded secrets when restoration fails (including when env vars are missing). These issues directly undermine the security goal (#9813). - src/config/env-substitution.ts, src/config/io.ts <!-- greptile_other_comments_section --> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs