fix(failover): treat a set-but-empty api_key_env as unset in ResolveAPIKey

Matches cloud-proxy's resolveAPIKey exactly: os.Getenv + empty check
rather than os.LookupEnv, so a variable that's set but empty errors
instead of probing unauthenticated.

Assisted-by: Claude:claude-opus-5-5
This commit is contained in:
Ettore Di Giacinto committed 2026-09-26 15:59:25 +00:00
1 parent f45bb1aa41
commit ad66a23208
2 files changed
+12 -5

No files matched your search

+7 -5
View File
@@ -303,19 +303,21 @@ const (
)
// ResolveAPIKey returns the upstream key from api_key_env or api_key_file, or
// "" when neither is set. The cloud-proxy backend applies the same rules.
// "" when neither is set. Mirrored (not imported, to keep backends independent
// of core's package layout) by resolveAPIKey in backend/go/cloud-proxy/proxy.go
// — keep the two in sync, empty-value handling included.
func (p ProxyConfig) ResolveAPIKey() (string, error) {
switch {
case p.APIKeyEnv != "":
v, ok := os.LookupEnv(p.APIKeyEnv)
if !ok {
return "", fmt.Errorf("proxy api_key_env %q is not set", p.APIKeyEnv)
v := os.Getenv(p.APIKeyEnv)
if v == "" {
return "", fmt.Errorf("proxy api_key_env %q is unset", p.APIKeyEnv)
}
return v, nil
case p.APIKeyFile != "":
b, err := os.ReadFile(p.APIKeyFile)
if err != nil {
return "", fmt.Errorf("proxy api_key_file: %w", err)
return "", fmt.Errorf("proxy api_key_file %q: %w", p.APIKeyFile, err)
}
return strings.TrimSpace(string(b)), nil
}
@@ -78,6 +78,11 @@ var _ = Describe("ProxyConfig.ResolveAPIKey", func() {
_, err := ProxyConfig{APIKeyEnv: "FAILOVER_TEST_UNSET_KEY"}.ResolveAPIKey()
Expect(err).To(HaveOccurred())
})
It("fails on a set-but-empty env var", func() {
GinkgoT().Setenv("FAILOVER_TEST_EMPTY_KEY", "")
_, err := ProxyConfig{APIKeyEnv: "FAILOVER_TEST_EMPTY_KEY"}.ResolveAPIKey()
Expect(err).To(HaveOccurred())
})
It("reads and trims the key file", func() {
f := filepath.Join(GinkgoT().TempDir(), "key")
Expect(os.WriteFile(f, []byte(" k2\n"), 0o600)).To(Succeed())