---
cuppy_hub: gcp
cuppy_path: guides/databases/connect-to-cloud-sql-with-iam-auth.md
cuppy_section: docs
cuppy_doc: 2WAR-8T70
cuppy_doc_uuid: caa1e57c-252c-4bb8-a445-6fb126dcfdf7
cuppy_permalink: https://cuppy.io/gcp/d/2WAR-8T70
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/gcp/docs/guides/databases/connect-to-cloud-sql-with-iam-auth
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 9e79f9415570907c4c409ddc39fab87fc74eb878bb8d9705a2409a04eb8334cc
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# 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 `GRANT`s 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`.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 91 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/gcp/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
