Connect to Cloud SQL with no database credential to manage
Seven steps to a connection authorised by the workload's own identity: private IP, a dedicated service account, roles/cloudsql.client, an IAM database user, a language connector or the Auth Proxy, then a verification that proves no password exists in the path.
markdownguidev12WAR-8T70stage: buildtrust: officialfamily: databasesservice: cloud-sqlinterface: sdkcloud SQLIAM database authenticationroles/cloudsql.clientCloud SQL Auth ProxyCloud SQL Language Connectorsprivate IPservice accountshort-lived access token
Connect to Cloud SQL without a stored credential
The target state: no password anywhere. The connection is authorised by the workload's own identity, and the only thing in configuration is the instance's name.
Step 1 — give the instance a private IP, not a public one
Private IP makes the instance reachable from the VPC network and not from the internet. If the client genuinely cannot be in the VPC, the vendor's instruction is explicit:
"If you're connecting to an instance by a public IP address, use a Cloud SQL connector (either the Cloud SQL Auth Proxy or one of the Cloud SQL Language Connectors)."
An authorized-networks allowlist is the weaker answer and should be the last one.
Step 2 — a dedicated service account for the workload
One per workload, attached to the compute resource. No keys: a service account key is "a security risk if not managed correctly", and the attached-identity path exists precisely so that one is never needed.
Step 3 — grant roles/cloudsql.client
On the instance's project, to that service account. This is the grant that lets a connector open the connection at all, and its absence is the commonest cause of a connector failure that reads like a network fault.
Step 4 — create the database user as an IAM principal
Cloud SQL has two authentication types and they are not interchangeable:
| Type | What the client presents |
|---|---|
| built-in database authentication | a username and a password |
| IAM database authentication | a short-lived access token for an IAM principal |
Create the user as the second kind, named for the service account. There is then no password to store, rotate, or leak.
Step 5 — connect with a connector, not a raw driver
Use a Cloud SQL Language Connector — Java, Python, Go or Node.js — or the Cloud SQL Auth Proxy for anything else. The connector obtains the credential from the ambient identity and handles the transport; a raw driver pointed at an address does neither.
Step 6 — grant the in-database privileges
IAM decides whether you may connect. The database's own GRANTs decide what you may read and write. They
are two systems and both are required — an IAM user with no table grants connects successfully and can do
nothing, which reads like a broken configuration and is not.
Step 7 — verify, including the failure you want
| Check | Expected |
|---|---|
| connect from the workload | success, with no password in any configuration or secret |
| grep the deployment for a database password | nothing — if there is one, step 4 did not happen |
remove roles/cloudsql.client and retry | the connection fails. That proves which control is carrying the authorisation |
| trigger or await a failover (HA uses a standby VM in another zone) | the client reconnects. A pool that does not retry turns a designed failover into an outage |
For a migration
This removes the database credential from the inventory of secrets entirely — not rotated, absent. The
counterparts are IAM authentication for Amazon RDS and Microsoft Entra authentication for Azure Database for
PostgreSQL/MySQL, and the shape is similar enough that the design ports. See guides/parity/databases.md.