From 0c1380d643573228a94ee06b83d62edd7ccd485a Mon Sep 17 00:00:00 2001 From: Jonathan Hess Date: Thu, 22 Jan 2026 12:19:30 -0700 Subject: [PATCH 1/2] fix: Correctly set the credentials token source WIP: needs unit tests Fixes #2542 --- internal/proxy/proxy.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index a28759553..73456b67c 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -363,7 +363,20 @@ func credentialsOpt(c Config, l cloudsql.Logger) (cloudsqlconn.Option, error) { if err != nil { return nil, err } + + var iamAuthNEnabled bool if c.IAMAuthN { + iamAuthNEnabled = true + } else { + for _, ic := range c.Instances { + if ic.IAMAuthN != nil && *ic.IAMAuthN { + iamAuthNEnabled = true + break + } + } + } + + if iamAuthNEnabled { iamLoginTS, err := impersonate.CredentialsTokenSource( context.Background(), impersonate.CredentialsConfig{ From 4fc6bc8e464f4b1e72d5932e67baa1e2f45cb375 Mon Sep 17 00:00:00 2001 From: Michael Ruoss Date: Fri, 23 Jan 2026 09:18:00 +0100 Subject: [PATCH 2/2] fix: Correctly set the credentials token source and the WithIAMAuthN opt --- internal/proxy/proxy.go | 30 ++++++++++++++++-------------- tests/postgres_test.go | 8 ++++++++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index 73456b67c..0b023df3f 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -323,6 +323,20 @@ func parseImpersonationChain(chain string) (string, []string) { const iamLoginScope = "https://www.googleapis.com/auth/sqlservice.login" +// iamAuthNEnabled returns true if IAM authentication is enabled globally +// or for any instance in the configuration. +func (c *Config) iamAuthNEnabled() bool { + if c.IAMAuthN { + return true + } + for _, inst := range c.Instances { + if inst.IAMAuthN != nil && *inst.IAMAuthN { + return true + } + } + return false +} + func credentialsOpt(c Config, l cloudsql.Logger) (cloudsqlconn.Option, error) { // If service account impersonation is configured, set up an impersonated // credentials token source. @@ -364,19 +378,7 @@ func credentialsOpt(c Config, l cloudsql.Logger) (cloudsqlconn.Option, error) { return nil, err } - var iamAuthNEnabled bool - if c.IAMAuthN { - iamAuthNEnabled = true - } else { - for _, ic := range c.Instances { - if ic.IAMAuthN != nil && *ic.IAMAuthN { - iamAuthNEnabled = true - break - } - } - } - - if iamAuthNEnabled { + if c.iamAuthNEnabled() { iamLoginTS, err := impersonate.CredentialsTokenSource( context.Background(), impersonate.CredentialsConfig{ @@ -452,7 +454,7 @@ func (c *Config) DialerOptions(l cloudsql.Logger) ([]cloudsqlconn.Option, error) opts = append(opts, cloudsqlconn.WithUniverseDomain(c.UniverseDomain)) } - if c.IAMAuthN { + if c.iamAuthNEnabled() { opts = append(opts, cloudsqlconn.WithIAMAuthN()) } diff --git a/tests/postgres_test.go b/tests/postgres_test.go index 58afa4b75..fe6400d02 100644 --- a/tests/postgres_test.go +++ b/tests/postgres_test.go @@ -280,6 +280,14 @@ func TestPostgresIAMDBAuthn(t *testing.T) { dsn: fmt.Sprintf("host=localhost user=%s database=%s sslmode=disable", impersonatedIAMUser, *postgresDB), }, + { + desc: "using impersonation with query param", + args: []string{ + "--impersonate-service-account", *impersonatedUser, + fmt.Sprintf("%s?auto-iam-authn=true", *postgresConnName)}, + dsn: fmt.Sprintf("host=localhost user=%s password=password database=%s sslmode=disable", + impersonatedIAMUser, *postgresDB), + }, } for _, tc := range tcs { t.Run(tc.desc, func(t *testing.T) {