---
cuppy_hub: gcp
cuppy_path: patterns/cloud-run-to-cloud-sql-with-iam.md
cuppy_section: docs
cuppy_doc: ANX6-HFVE
cuppy_doc_uuid: 04711858-99bf-4e92-8c7b-09b6cf2fa7fe
cuppy_permalink: https://cuppy.io/gcp/d/ANX6-HFVE
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/gcp/docs/patterns/cloud-run-to-cloud-sql-with-iam
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: e7c04bfa5a496996fd80e40e53a22b2e6d6bcc74bdc2e25d376d93e462960dba
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Cloud Run → Cloud SQL, with no password

## The handoff

```
Cloud Run service  (its OWN service account, attached)
   │  roles/cloudsql.client            ← may open the connection
   │  roles/secretmanager.secretAccessor  ← only if it must read a secret at all
   ▼
Cloud SQL connector  (Language Connector, or the Auth Proxy)
   │  presents a SHORT-LIVED ACCESS TOKEN for the service account
   ▼
Cloud SQL instance  (PRIVATE IP, reachable from the VPC)
   │  the database user IS the IAM principal
   ▼
in-database GRANTs decide what it may read and write
```

Build order: `guides/databases/connect-to-cloud-sql-with-iam-auth.md`. The deploy side:
`guides/compute/deploy-a-container-on-cloud-run.md`.

## The three gates, which are three different systems

| Gate | Decides | Grant |
|---|---|---|
| IAM on the instance's project | may this identity **open** a connection | `roles/cloudsql.client` |
| the database's own user model | **who** it is in the database | an IAM database authentication user |
| the database's `GRANT`s | **what** it may read and write | SQL, not IAM |

**All three are required and none implies another.** An identity with the first two connects successfully and
can do nothing — which looks like a broken configuration and is a missing `GRANT`.

## Known-bad configurations

### 1. A password in Secret Manager

It works. It is still the wrong pattern: a credential exists, so it can leak, must rotate, and appears in an
inventory. **IAM database authentication removes the credential rather than protecting it.** If the design
needs a secret at all, make sure the runtime identity has `roles/secretmanager.secretAccessor` — the **viewer**
role cannot read a payload, and that mistake is the commonest cause of the 503 below.

### 2. A public IP with an authorized-networks allowlist

The vendor's own instruction: *"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 address allowlist
is the weaker answer and ages badly — Cloud Run egress addresses are not a fixed set unless you make them one.

### 3. The default service account

The default Compute Engine service account is shared, broadly privileged, and sometimes deleted by a tidy
administrator — which produces the deploy-time *"User does not have permission to access namespace"*. One
service account per service, passed with `--service-account`.

### 4. A connection pool that does not reconnect

Cloud SQL HA fails over to **a standby VM in another zone**, and a **maintenance update** requires an
**instance restart**. Both are designed, scheduled events. A pool that treats a dropped connection as fatal
turns either one into an outage. **Configure the maintenance window too** — the default is an arbitrary hour.

### 5. A pool sized per instance in a service that scales to many instances

Cloud Run scales out. `maxConnections` is per process, so the database sees pool size × instance count.
Size the pool against the instance ceiling, not against one container.

## The failure you will actually meet

```
HTTP 503  The request failed because the instance could not start successfully.
```

Documented causes: **missing secrets**, IAM, network. Check in that order:

1. can the runtime identity read the secret? (`secretAccessor`, not `viewer`)
2. does it hold `roles/cloudsql.client`?
3. is the egress path to the private IP open?

A **429** is something else entirely — capacity, not configuration
(`reference/compute/errors.md` §4).

## Verification

| Test | Expected |
|---|---|
| the service answers a request that touches the database | **200** |
| grep the whole deployment for a database password | **nothing** |
| remove `roles/cloudsql.client` and redeploy | the connection fails — proving which control carries it |
| trigger or await a failover | the service **reconnects** |
| scale to the instance ceiling under load | the database connection count stays within its limit |


---
<!-- 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 -->
