IAM DB auth for Cloud SQL: when it simplifies security and when it complicates delivery
IAM DB auth can reduce password sprawl and make revocation cleaner, but it also turns database access into an identity operating model that depends on disciplined service-account boundaries.
IAM database authentication replaces a distributed password with a short-lived login derived from a Google identity. It works well when workload identity is already a trustworthy boundary, but becomes awkward when service accounts are shared, local access is improvised, or nobody owns the grants that now control database entry.
The feature removes secret rotation work. It doesn’t remove the need to design database principals and authorization.
Separate three layers
Cloud SQL access involves three related controls:
- Network reachability determines whether the client can reach the instance.
- Cloud IAM authorization permits the principal to connect and log in through the Cloud SQL path.
- PostgreSQL roles and grants determine what the database principal may do.
IAM database authentication changes the login credential. A connector or the Auth Proxy can create and refresh the short-lived token automatically. Private IP, public IP, Direct VPC egress, and authorized network design remain separate decisions. PostgreSQL schemas, roles, and grants remain separate too.
Keeping these layers distinct makes failures diagnosable. Otherwise, “IAM auth is broken” covers routing, connector authorization, token generation, user mapping, and SQL privileges.
Use one workload identity per meaningful trust boundary
The clean production shape is one service account for one workload or a small group of workloads with the same owner and database rights.
Map that identity to a PostgreSQL IAM user, then grant it a database role representing application capability. Avoid granting application privileges directly to many individual principals where a stable database role can hold them.
Cloud Run service account
→ IAM permission to connect and log in
→ PostgreSQL IAM user
→ application database role
→ schema and object privilegesDon’t reuse one broad service account across APIs, workers, migrations, and environments merely because the authentication mechanism is modern. A shared identity recreates the blast radius of a shared password and makes revocation more theatrical.
Prefer automatic token handling for applications
IAM database login tokens are short-lived. Long-running applications should use a supported Cloud SQL language connector or Auth Proxy with automatic IAM database authentication rather than generating a password once at startup and assuming it lasts forever.
The application pool still owns connection lifetime. Existing PostgreSQL sessions can continue after the token used to create them expires, but new connections need fresh authentication. Configure maximum connection lifetime and test pool recovery so token refresh, certificate refresh, and managed maintenance don’t produce a synchronized reconnect failure.
A connector authenticates the Cloud SQL connection. It doesn’t pool database sessions. Keep the connection budget and local pool limits.
Human access needs another path
Developers and operators should connect through named personal identities or controlled group membership where supported, not impersonate the production application casually.
Define the workflow for local development, production diagnosis, migrations, and break-glass access. The answer may include service-account impersonation, Cloud SQL Auth Proxy, personal IAM database users, a bastion or private network path, and a tightly governed emergency credential.
A residual password is acceptable when it solves a specific recovery requirement and its custody, rotation, use, and audit are explicit. Pretending it doesn’t exist because production services use IAM is less acceptable.
Provisioning order becomes part of delivery
A deployment using IAM database authentication may require:
- APIs and instance settings enabled
- service account created
- Cloud IAM roles granted
- IAM database user created
- PostgreSQL roles and grants applied
- connector or proxy configured
- network path available
Model those dependencies in infrastructure and migrations. A service revision shouldn’t discover at startup that its Google identity exists but its PostgreSQL principal or grants don’t.
Separate infrastructure authority from database migration authority. The principal allowed to create IAM bindings doesn’t automatically need broad rights inside every schema.
Revocation is cleaner only when ownership is clean
IAM makes it easier to remove one workload’s ability to authenticate without rotating a credential used by others. Use that advantage.
Review service-account bindings and database membership together. Removing the Cloud IAM login role while leaving a powerful PostgreSQL role orphaned may block immediate access but leaves confusing state for the next provisioning mistake. Removing the database user without updating deployment configuration creates noisy failures instead of a controlled retirement.
Offboarding should remove or disable the workload, revoke IAM access, clean up database role membership, and preserve audit evidence.
Observe identity through the whole path
Log the Cloud Run service account, Cloud SQL connection errors, database user, application name, and relevant query tags. Operators should be able to map a PostgreSQL session back to a deployed workload and revision.
Alert separately on network failures, connector or IAM authorization failures, database authentication failures, and SQL permission errors. They have different owners and repair paths.
Test revocation and token refresh before production relies on them. Security controls that have never been exercised tend to become discovery exercises at the least charming possible time.
When passwords remain calmer
A conventional database credential can remain the smaller honest system for a legacy application, third-party tool, unsupported client, or tiny isolated workload whose identity integration would add several brittle dependencies.
That credential should still be unique to the workload, stored in Secret Manager, rotated, audited, and granted through a narrow PostgreSQL role. Shared permanent passwords aren’t made disciplined by being familiar.
Use IAM database authentication when it consolidates database login around identities the platform already owns well. Delay it when workload identity, local access, or provisioning is still ambiguous. Removing the password is useful only when the replacement trust path is easier to explain and revoke.
More in this domain: Infrastructure
Browse allHow we decide between Cloud SQL connectors, Auth Proxy, and private IP
Cloud SQL connectors, the Auth Proxy, and private IP are not interchangeable secure connection options. They change identity, routing, deployment shape, and how much network plumbing the team actually owns.
Safe scaling defaults for Cloud Run + Postgres
Cloud Run autoscaling is not a database strategy. Safe defaults keep the application from scaling itself into a Postgres incident before the team understands the workload.
Cloud Run request timeouts don't kill your code (so your architecture has to)
A Cloud Run request timeout ends the request, not necessarily the work. If the operation can outlive its caller, the system needs explicit job semantics instead of hope.
Cloud Run scaling from zero is a feature until it isn't
Scale to zero is a good default for request-driven services, until startup delay, warm-capacity needs, or instance caps turn it into user-visible reliability behavior instead of a pricing feature.
Direct VPC egress vs Serverless VPC Access for Cloud Run: our default
We default to Direct VPC egress for Cloud Run because it is the cleaner networking shape: fewer moving parts, no connector resource, and costs that scale with the service instead of beside it.
Related patterns
"Internal-only" Cloud Run isn't just a checkbox
Making a Cloud Run service private is not one toggle. It is a decision about ingress, routing, caller path, and IAM working together as one access model.
How we treat Terraform state in team environments
Terraform starts feeling fragile in teams when state is treated like a backend setting instead of a shared dependency for safe change.
Why Cloud Run + Postgres needs a connection budget
Cloud Run and Postgres get fragile when connection growth is left implicit. We treat connections as a finite runtime budget, not as plumbing the app can multiply without consequence.
GKE Autopilot as the escape hatch from Cloud Run
When Cloud Run stops fitting, the next move is usually GKE Autopilot: more Kubernetes-shaped control without immediately taking on the full burden of Standard clusters.