Google Cloud SQL ships with defaults that favour easy connection over security: unencrypted connections are accepted, public IP is allowed unless an organisation policy blocks it, and database passwords are still the path of least resistance. Each of those defaults can be changed, but only if you know where the settings live and which IAM roles quietly allow data export. This guide covers how identity and access work in Cloud SQL, the privileged roles, how applications and service accounts should connect, what to log, and a hardening baseline. Specific settings are taken from the Cloud SQL for PostgreSQL documentation; MySQL and SQL Server editions share the same connection, IAM and encryption model but differ in engine-level details such as audit extensions. It is written for cloud engineers, database administrators and security architects on Google Cloud. For engine-neutral credential practice, see the Database Credential and Access Security Guide.
This is an independent guide from NHI Mgmt Group, based on Google Cloud's public documentation as of November 2026. It is not sponsored or reviewed by Google Cloud. Product features change, so confirm settings against Google Cloud's current documentation.
Key takeaways
- The default SSL mode accepts plain text.
sslModedefaults toALLOW_UNENCRYPTED_AND_ENCRYPTED; setENCRYPTED_ONLYorTRUSTED_CLIENT_CERTIFICATE_REQUIRED, and remember the change only affects new connections. - IAM database authentication removes stored passwords. Users, service accounts and IAM groups log in with one-hour OAuth tokens that the Cloud SQL Auth Proxy or language connectors refresh automatically.
- Editor can export your data.
roles/cloudsql.editorincludescloudsql.instances.export, so treat it as a data-read role, not a configuration role. - Private IP and organisation policies set the perimeter. Private Service Connect is the default private option for new projects, and
constraints/sql.restrictPublicIpandconstraints/sql.restrictAuthorizedNetworksstop public exposure before it starts. - Logins and SQL are only visible if you turn on Data Access logs.
instances.login,executeSql,exportand pgAudit records are all Data Access audit logs, which are off by default for most services.
How identity and access work in Google Cloud SQL
Cloud SQL has two layers of identity, and a secure design controls both.
| Layer | Question it answers | Mechanism |
|---|---|---|
| Cloud IAM (control plane) | Who can create, change, export, connect to or log in to the instance | Cloud SQL IAM roles on project, folder or organisation |
| Network path | Which networks can reach the database port | Private IP (Private Service Connect or private services access), public IP with authorized networks, or connectors |
| Database authentication | Who the session is inside the engine | IAM database authentication or built-in (password) users |
| Database authorisation | What the session can read and change | Engine privileges (PostgreSQL GRANT) |
IAM database authentication
- Automatic login (recommended): the Cloud SQL Auth Proxy or the Go, Java or Python language connectors obtain and refresh tokens; the client passes only the IAM database username.
- Manual login: the principal fetches an OAuth 2.0 token (for example with gcloud) and uses it as the password. Tokens last one hour, so new connections fail after expiry; avoid manual login for pooled or long-running applications.
- Principals: user accounts, service accounts and IAM groups. With groups, members log in with their own credentials and Cloud SQL creates a database account for each member on first login; an instance supports up to 200 IAM groups. Group members inherit the database privileges granted to the group.
- Requirements: the
cloudsql.iam_authenticationflag must be on (the console enables it by default for new instances); the principal needscloudsql.instances.login, which is in Cloud SQL Instance User (roles/cloudsql.instanceUser); usernames are lowercase; only SSL connections are accepted. - IAM is not authorisation inside the database: when you create IAM users through gcloud or the API you must still grant engine privileges yourself. Removing someone from one group revokes that group's privileges, but they may still log in through another group.
- Known limits: Google documents a cap of 12,000 logins per minute per instance, slow IAM logins on CPU-throttled shared-core machines, and that context-aware access blocks connector-based IAM logins.
Built-in users
Built-in users authenticate with a username and password. If you must keep them, enable the instance password policy (it is off until you enable it): minimum length, complexity, restrict password reuse, disallow username, and password change interval. User-level settings add password expiry and account lockout after failed attempts. Password policy does not apply to hashed passwords, and replicas inherit the primary's policy.
Admin roles and privileged access
| Role | What it allows | Risk to manage |
|---|---|---|
Cloud SQL Admin (roles/cloudsql.admin) | Full control, including cloudsql.users.update, SSL certificates, import, restore, clone and delete | Can reset any built-in user's password and read all data; limit to break-glass and pipelines |
Cloud SQL Editor (roles/cloudsql.editor) | Most management, including exports, failover, restarts and updates; cannot modify users or SSL certificates | instances.export copies databases to Cloud Storage: a data exfiltration path |
Cloud SQL Viewer (roles/cloudsql.viewer) | Read-only resource view, plus backupRuns.export | Not purely metadata: review who holds it |
Cloud SQL Client (roles/cloudsql.client) | Connect through the Auth Proxy and App Engine (instances.connect) | Network-level reach only; database credentials still required |
Cloud SQL Instance User (roles/cloudsql.instanceUser) | login, get and executeSql | Grants IAM login and SQL execution through the API; pair with tight engine grants |
Cloud SQL Studio User (roles/cloudsql.studioUser) | Cloud SQL Studio: list databases and users, run SQL, log in | Browser-based query access; restrict to analysts who need it |
- Grant at the instance's project, not the organisation: Cloud SQL roles granted high in the hierarchy apply to every instance below.
- Separate export from operations: build a custom role for operators that keeps restart and failover but drops
cloudsql.instances.export. - Protect the engine superuser: keep the default administrative database user's password in a secret manager with no human copy, and use named IAM users for day-to-day DBA work so actions are attributable.
- Federate and elevate: humans should hold Admin only through time-bound elevation. See the Google Cloud IAM and Service Accounts Guide.
Integrations, API tokens and service accounts
Most Cloud SQL connections come from workloads, so service account hygiene decides most of your exposure.
| Connection pattern | Authorisation | Encryption | When to choose |
|---|---|---|---|
| Private IP, Cloud SQL connector, IAM auth | VPC reach, roles/cloudsql.client, IAM login | Automatic TLS with client and server identity verification | Default for new workloads |
| Private IP, direct, IAM or password auth | VPC reach plus database credentials | You configure sslMode and certificates | Clients that cannot run a connector; lowest latency |
| Public IP, connector | Connector identity plus database credentials; no authorized networks needed | Automatic TLS with identity verification | Clients outside Google Cloud, dynamic addresses |
| Public IP, direct, authorized networks | Source address allow list plus database credentials | You configure sslMode and certificates | Avoid; block with organisation policy where possible |
- Attached service accounts, not keys: run workloads on Cloud Run, GKE or Compute Engine with an attached service account and let the connector use its credentials. Downloaded service account keys turn database access into a file that can leak. See the Google Cloud Service Account Keys Security Guide.
- One service account per application: map each to its own IAM database user and its own engine grants, so a compromised service can read only its own schema.
- Prefer IAM database users to passwords: where a built-in password is unavoidable (legacy applications, third-party tools), store it in Secret Manager and rotate it. See the Secrets Management Guide.
- Client certificates are long-lived secrets: up to 10 per instance, valid for 10 years by default, with no expiry notification and no recovery of a lost private key. Inventory them, and prefer connectors, which handle certificates for you.
- Watch where credentials travel: database connection strings belong in a secret manager, never in tickets or chat.
Logging and detection
Cloud SQL writes Cloud Audit Logs under protoPayload.serviceName="cloudsql.googleapis.com". Admin Activity logs (always on) record changes such as instances.create, instances.update, instances.delete, instances.restoreBackup and sslCerts.create. Data Access logs, which you must enable, record instances.login, instances.executeSql, instances.import, instances.export, users.create and reads such as users.list. Google notes that tracking IAM database logins requires Data Access logs.
For SQL-level auditing on PostgreSQL, set cloudsql.enable_pgaudit=on (this restarts the instance), run CREATE EXTENSION pgaudit;, and set pgaudit.log (default none), for example to read,write for sensitive databases or per role. pgAudit records arrive as Data Access audit logs. Google warns that logs are buffered on the instance disk and ingested at up to 4 MB per second, so heavy logging can consume disk or drop records: enable automatic storage increase and watch cloudsql.googleapis.com/database/disk/utilization.
| Event | Log | Why it matters |
|---|---|---|
instances.export to an unfamiliar bucket | Data Access | Bulk exfiltration (ATT&CK T1530 Data from Cloud Storage once exported) |
instances.update adding authorized networks or public IP, or lowering sslMode | Admin Activity | Perimeter change to review |
users.create and other user changes | Data Access | New backdoor user or unexpected password reset |
Spikes in failed instances.login | Data Access | Credential guessing (T1110 Brute Force) or broken rotation |
| Service account logging in from an unexpected workload | Data Access plus IAM logs | Stolen credentials (T1078.004 Cloud Accounts) |
| pgAudit reads on sensitive tables outside normal roles | pgAudit | Data access by an unexpected role |
See the Google Cloud Audit Logs and Log Sinks Guide and the Database Audit Log Detection Guide.
Metrics
- Encryption in transit: share of instances with
sslModeset toENCRYPTED_ONLYor stricter; target 100%. - Public exposure: instances with a public IP or authorized networks; target zero outside documented exceptions.
- Passwordless share: percentage of application connections using IAM database authentication.
- Export holders: number of principals with
cloudsql.instances.exporton production projects. - Audit coverage: production instances with Data Access logs and pgAudit (or the engine equivalent) enabled.
Hardening baseline
- Set organisation policies first: enforce
constraints/sql.restrictPublicIpandconstraints/sql.restrictAuthorizedNetworks, and, if you require customer-managed keys,constraints/gcp.restrictNonCmekServicesforsqladmin.googleapis.complusconstraints/gcp.restrictCmekCryptoKeyProjects. Google notes these are not retroactive: they apply at creation, restart, cloning and similar operations, so audit existing instances separately. See the Google Cloud Organization Policy Guide. - Use private IP: Private Service Connect for multi-network or cross-project access, private services access for a single VPC. See the Google Cloud VPC and Cloud NGFW Security Guide.
- Enforce TLS: set
sslModetoENCRYPTED_ONLY, orTRUSTED_CLIENT_CERTIFICATE_REQUIREDwhere all clients use connectors or managed certificates. Restart in a maintenance window to drop existing unencrypted sessions. - Choose a server CA mode deliberately: per-instance CA (10-year server certificates), shared CA (1-year, verify CA and hostname) or customer-managed CA through Certificate Authority Service (1-year or shorter, custom SANs). Enable rotation before expiry notices at 90 days.
- Switch applications to IAM database authentication through connectors, and enable the instance password policy for any remaining built-in users.
- Decide on CMEK at creation: it cannot be added later. Keys must be in the instance's region; disabling a key suspends the instance, and destroying the original key version makes data and backups unrecoverable. See the Cloud KMS and Cloud HSM Guide.
- Right-size IAM: remove Editor from humans, build an operator role without export, and keep Admin for pipelines and break-glass.
- Enable Data Access logs and pgAudit for production, routed to a central log project.
Testing and rollback: trial sslMode and IAM authentication changes on a clone or staging instance first, check connection errors in client logs, and keep the built-in user available until every client has moved. sslMode can be relaxed again if a critical client breaks; network type moves and CMEK cannot be reversed in place.
Small vs large estates: a small team can reach most of this baseline with private IP, connectors, IAM authentication and two organisation policies. Larger estates should add CMEK with key project restrictions, separate projects per data classification and automated drift checks.
Common misconfigurations
- Default
sslModeleft in place: applications connect without TLS on private IP because "the VPC is private". - Authorized network of
0.0.0.0/0: added for a quick test and never removed, exposing the instance to password guessing. - Editor granted for convenience: developers can export whole databases to buckets they control.
- Manual IAM tokens in long-lived pools: connections fail an hour after deployment and teams fall back to passwords.
- pgAudit enabled without Data Access logs or disk headroom: nothing reaches Cloud Logging, or records are dropped under load.
- Service account keys for connectors: a JSON key on a laptop or in a repository becomes a permanent database credential.
Framework mapping
| Framework | Reference | Cloud SQL control |
|---|---|---|
| NIST SP 800-53 Rev. 5 | IA-2, IA-5 | IAM database authentication, password policy |
| NIST SP 800-53 Rev. 5 | AC-2, AC-6 | Per-application service accounts, roles without export |
| NIST SP 800-53 Rev. 5 | SC-7, SC-8 | Private IP, organisation policies, sslMode |
| NIST SP 800-53 Rev. 5 | SC-12, SC-28 | CMEK and key management |
| NIST SP 800-53 Rev. 5 | AU-2, AU-12 | Data Access logs, pgAudit |
| NIST CSF 2.0 | PR.AA-05, PR.DS-01, PR.DS-02, PR.PS-04 | Access policy, data at rest and in transit, logging |
Practitioner checklist
- Enforce
sql.restrictPublicIpandsql.restrictAuthorizedNetworksat the organisation and list existing instances that predate them. - Set
sslModetoENCRYPTED_ONLYor stricter on every instance and restart to close old sessions. - Move application connections to Cloud SQL connectors with IAM database authentication and attached service accounts.
- Enable the instance password policy and lockout for any remaining built-in users; store their passwords in a secret manager.
- Remove
roles/cloudsql.editorfrom humans and audit every holder ofcloudsql.instances.export. - Inventory client certificates and server CA expiry dates; enable rotation.
- Enable Data Access audit logs for Cloud SQL and pgAudit (or the engine equivalent) on production instances, with alerts on exports and user changes.
- Decide CMEK requirements before creating new production instances.
Standards and references
- Google Cloud: Cloud SQL IAM database authentication
- Google Cloud: Cloud SQL connection options
- Google Cloud: Configure SSL/TLS certificates for Cloud SQL
- Google Cloud: Cloud SQL IAM roles
- Google Cloud: Cloud SQL audit logging
- Google Cloud: Cloud SQL organisation policies
- Google Cloud: Customer-managed encryption keys for Cloud SQL
- NIST: SP 800-53 Rev. 5
Related NHI Mgmt Group resources: Database Credential and Access Security Guide · Google Cloud Security Guide · BigQuery Security Guide · Database Security Guide