Create the Google Secret Manager client only when a mapping uses GSM#35
Create the Google Secret Manager client only when a mapping uses GSM#35nullzone wants to merge 3 commits into
Conversation
main() unconditionally builds a Google Secret Manager client via secretmanager.NewClient(ctx) at startup, regardless of whether any mapping actually sources from GSM. Because the Google SDK resolves Application Default Credentials eagerly at construction time, this makes GCP credentials a hard startup requirement for every deployment, including pure-Vault ones that never touch GSM.
On a non-GCP environment (e.g. Vault-only secret reflection in an on-prem/other-cloud cluster) pentagon therefore dies at startup with:
unable to get GSM client: credentials: could not find default credentials
and exits 32, even though the GSM client is never used.
Build the GSM client lazily: scan the configured mappings and only call secretmanager.NewClient when at least one mapping has SourceType == GSMSourceType. When no mapping uses GSM the client stays nil and is never dereferenced (Reflector.getGSMSecret is only reached for GSM-sourced mappings), so Vault-only deployments no longer require any GCP credential. Behaviour is unchanged when GSM mappings are present: a missing/invalid credential still fails fast.
Create the GSM client only when a mapping uses GSM
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 8f49f34. Configure here.
| if err != nil { | ||
| log.Printf("unable to get GSM client: %s", err) | ||
| os.Exit(32) | ||
| var gsmClient *secretmanager.Client |
There was a problem hiding this comment.
Typed nil pointer creates non-nil interface value
Low Severity
gsmClient is declared as *secretmanager.Client (a concrete type). When no GSM mappings exist, this typed nil pointer is passed to NewReflector, which expects the gsm.SecretAccessor interface. In Go, a typed nil pointer wrapped in an interface produces a non-nil interface value. So Reflector.gsmClient will not be nil — it will be a non-nil interface holding a nil pointer. Any future nil guard on r.gsmClient would incorrectly pass, and calling a method on it would panic. Declaring gsmClient as gsm.SecretAccessor instead would preserve a true nil interface when unused.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 8f49f34. Configure here.
Declare gsmClient as gsm.SecretAccessor instead of the concrete *secretmanager.Client. A typed nil pointer assigned to an interface yields a non-nil interface value wrapping a nil pointer, so when no mapping uses GSM the previous code left Reflector.gsmClient non-nil, silently defeating any nil check and panicking if a method were called. Construction and Close() use a concrete *secretmanager.Client local that is then assigned to the interface variable, since SecretAccessor exposes only AccessSecretVersion (no Close).


Problem
main()builds a Google Secret Manager client unconditionally at startup (secretmanager.NewClient(ctx)), regardless of whether any mapping sources from GSM. The Google SDK resolves Application Default Credentials eagerly at construction, so GCP credentials become a hard startup requirement for every deployment — including pure-Vault ones that never touch GSM.On a non-GCP cluster (e.g. Vault-only reflection on-prem) pentagon dies at startup with:
unable to get GSM client: credentials: could not find default credentials
(exit code 32), even though the GSM client is never used.
Fix
Build the GSM client lazily: only call
secretmanager.NewClientwhen at least one mapping hasSourceType == GSMSourceType. When no mapping uses GSM the client staysniland is never dereferenced —Reflector.getGSMSecretis only reached for GSM-sourced mappings — so Vault-only deployments no longer need any GCP credential.Behaviour
gsmmapping: unchanged — a missing/invalid credential still fails fast at startup.Testing
go test ./...passes.gsmmapping still requires the GSM client.