Support GCP Cloud SQL with IAM Database Authentication (and Workload Identity Federation) #3565
Replies: 1 comment 3 replies
|
Thanks for the detailed write-up @akshat-kumar-singhal — this is a good idea and well scoped. Rather than branching inside core sql.NewSQL, the cleaner fit is to support this the way every other datasource already works: add an AddSQLDB method on the app that lets users plug in their own SQL implementation (e.g. a Cloud SQL IAM connection), overriding the default. This ties into work we already have queued up: #2113 (Separate out datasources to a new repo) — the longer-term plan is to pull SQL and Redis out of core into self-contained modules, with core keeping only the interface and a registry doing the wiring. SQL and Redis are the last two still baked into core. #1259 (Remove datasources' dependency on GoFr) — same north star from the other side: datasources shouldn't be coupled to a specific GoFr version. Fully removing SQL and Redis from core today (as #2113 envisions) would be a breaking change — it'd force a v2, which we don't want to do right now. AddSQLDB gets us most of the way there without breaking anything: it's purely additive, so no v2, and it's exactly the plug-in seam the #2113 registry will need anyway. So this moves us toward that refactor rather than against it. A few things this gets us at once:
|
Uh oh!
There was an error while loading. Please reload this page.
Summary
Add first-class support in GoFr's SQL datasource for connecting to GCP Cloud SQL (Postgres & MySQL) using IAM Database Authentication, with credentials resolved via Application Default Credentials so that Workload Identity Federation (WIF) works transparently — no service-account keys on disk, no static
DB_PASSWORD, no Cloud SQL Auth Proxy sidecar.Motivation
Today,
pkg/gofr/datasource/sqlaccepts a staticDBConfig(DB_USER/DB_PASSWORD) read once at startup and passed tosql.Open. That works fine for self-hosted Postgres/MySQL but leaves GCP users with three poor options:database/sqland skip GoFr's SQL datasource entirely, losing health checks, metrics, retries, and OTel tracing.Modern GCP deployments (GKE Workload Identity, Cloud Run, GitHub Actions via WIF) increasingly prohibit long-lived service-account keys. GoFr should make the secret-less path the easy path.
Proposal
Reuse the existing
DB_DIALECTvalues (postgres,mysql) and introduce a single switch:When
DB_IAM_AUTH=true,NewSQLusescloud.google.com/go/cloudsqlconnwithWithIAMAuthN()to mint and auto-refresh OAuth2 tokens used as the DB password;DB_PORTandDB_SSL_MODEare ignored (the connector owns TLS). Health checks, retry-on-disconnect, metrics, and OTel tracing match existingNewSQLbehavior.Packaging — separate module to keep core lean
cloudsqlconnbrings ~30 transitive GCP SDK deps. To avoid taxing every GoFr binary, the implementation would live in a new modulepkg/gofr/datasource/sql/cloudsql/(mirroringmongo,gcs, etc.). Coresql.goadds a small routing branch: whenDB_IAM_AUTH=true, delegate driver registration to the cloudsql module. Users who don't import the module and don't setDB_IAM_AUTHsee zero behavior or dependency change.Out of scope (for the initial PR)
alloydbconn.database/sql-shaped; needs a different datasource interface.Questions for the maintainers
sql.NewSQLthat delegates to the cloudsql module whenDB_IAM_AUTH=true? Alternative is an explicitapp.AddSQL(cloudsql.New())call (zero core change but two config surfaces).DB_IAM_AUTHthe right name, or wouldDB_CLOUDSQL_IAM_AUTH(more explicit, leaves room for AWS RDS IAM later) read better?GOOGLE_APPLICATION_CREDENTIALSper Google's convention if they need to pin a key)?//go:build integrationgate keyed onCLOUDSQL_TEST_INSTANCEenv var, or keep maintainer-manual only?Happy to open the PR off
developmentonce direction is agreed.All reactions