Skip to content

Commit 129c591

Browse files
wesmclaude
andcommitted
fix: preserve provider auth env vars in cleanEnv allowlist
Add ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY, GOOGLE_APPLICATION_CREDENTIALS, GITHUB_TOKEN, GH_TOKEN, and COPILOT_ prefix to the env allowlist so users who authenticate via environment variables (including desktop.env) can generate insights without auth failures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent facd093 commit 129c591

2 files changed

Lines changed: 33 additions & 5 deletions

File tree

internal/insight/generate.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@ func GenerateStream(
101101
// safe to pass to agent CLI subprocesses. Matched
102102
// case-insensitively so Windows-style casing (Path, ComSpec)
103103
// is handled correctly. Using an allowlist prevents leaking
104-
// secrets to child processes.
104+
// arbitrary secrets to child processes while preserving
105+
// provider auth keys needed by the supported CLIs.
105106
var allowedKeyPrefixes = []string{
107+
// System
106108
"PATH",
107109
"HOME", "USERPROFILE",
108110
"USER", "USERNAME", "LOGNAME",
@@ -116,6 +118,16 @@ var allowedKeyPrefixes = []string{
116118
"SYSTEMROOT", "COMSPEC", "PATHEXT", "WINDIR",
117119
"HOMEDRIVE", "HOMEPATH",
118120
"APPDATA", "LOCALAPPDATA", "PROGRAMDATA",
121+
122+
// Provider auth (needed by agent CLIs)
123+
"ANTHROPIC_API_KEY",
124+
"OPENAI_API_KEY",
125+
"GEMINI_API_KEY",
126+
"GOOGLE_API_KEY",
127+
"GOOGLE_APPLICATION_CREDENTIALS",
128+
"GITHUB_TOKEN",
129+
"GH_TOKEN",
130+
"COPILOT_",
119131
}
120132

121133
// envKeyAllowed reports whether key (case-insensitive) is

internal/insight/generate_test.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@ func TestCollectStreamLines_LargeLine(t *testing.T) {
176176

177177
func TestCleanEnv(t *testing.T) {
178178
t.Setenv("ANTHROPIC_API_KEY", "sk-secret")
179+
t.Setenv("OPENAI_API_KEY", "sk-openai")
180+
t.Setenv("GEMINI_API_KEY", "gemini-key")
181+
t.Setenv("GOOGLE_API_KEY", "google-key")
182+
t.Setenv("GITHUB_TOKEN", "ghp_token")
183+
t.Setenv("GH_TOKEN", "gho_token")
184+
t.Setenv("COPILOT_AUTH", "copilot-val")
179185
t.Setenv("CLAUDECODE", "1")
180186
t.Setenv("HOME", "/home/test")
181187
t.Setenv("AWS_SECRET_ACCESS_KEY", "s3cret")
@@ -193,19 +199,22 @@ func TestCleanEnv(t *testing.T) {
193199
envMap[strings.ToUpper(k)] = v
194200
}
195201

196-
// Secrets and unknown vars must not pass through.
202+
// Unrelated secrets and unknown vars must not pass through.
197203
for _, blocked := range []string{
198-
"ANTHROPIC_API_KEY", "CLAUDECODE",
204+
"CLAUDECODE",
199205
"AWS_SECRET_ACCESS_KEY", "UNKNOWN_VAR",
200206
} {
201207
if _, ok := envMap[blocked]; ok {
202208
t.Errorf("%s should not be in env", blocked)
203209
}
204210
}
205211

206-
// Allowed system vars must pass through.
212+
// System vars and provider auth keys must pass through.
207213
for _, allowed := range []string{
208214
"HOME", "PATH", "LANG",
215+
"ANTHROPIC_API_KEY", "OPENAI_API_KEY",
216+
"GEMINI_API_KEY", "GOOGLE_API_KEY",
217+
"GITHUB_TOKEN", "GH_TOKEN", "COPILOT_AUTH",
209218
} {
210219
if _, ok := envMap[allowed]; !ok {
211220
t.Errorf("%s should be preserved", allowed)
@@ -244,7 +253,14 @@ func TestEnvKeyAllowed(t *testing.T) {
244253
{"WINDIR", true},
245254
{"HOMEDRIVE", true},
246255
{"HOMEPATH", true},
247-
{"ANTHROPIC_API_KEY", false},
256+
{"ANTHROPIC_API_KEY", true},
257+
{"OPENAI_API_KEY", true},
258+
{"GEMINI_API_KEY", true},
259+
{"GOOGLE_API_KEY", true},
260+
{"GOOGLE_APPLICATION_CREDENTIALS", true},
261+
{"GITHUB_TOKEN", true},
262+
{"GH_TOKEN", true},
263+
{"COPILOT_TOKEN", true}, // prefix match
248264
{"AWS_SECRET_ACCESS_KEY", false},
249265
{"DATABASE_URL", false},
250266
{"", false},

0 commit comments

Comments
 (0)