Back to Checks
gcp

Cloud SQL instance has no public IP addresses

cloudsql_instance_private_ip_assignment
Service: cloudsqlSeverity: high
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:sqladmin.googleapis.com/Instance

Cloud SQL instances are evaluated for IP assignment, highlighting instances that have any public IP instead of being restricted to private IP only.

Risk

Public database endpoints expose services to Internet scanning, brute-force logins, and exploit attempts. A compromise can cause data exfiltration (confidentiality), unauthorized changes (integrity), and outages or DDoS impact (availability), while bypassing VPC isolation and enabling lateral movement.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler gcp --checks cloudsql_instance_private_ip_assignment

Recommendation

Use private IP-only connectivity for databases. Remove public IPs, segment access to required VPCs/subnets, and enforce least privilege with strong auth and TLS. For external access, use secure private channels (VPN/Interconnect) or a hardened bastion. Monitor connections as part of defense in depth.

Remediation

CLI

gcloud beta sql instances patch <example_resource_id> --project=<example_project_id> --network=projects/<example_project_id>/global/networks/<example_resource_name> --no-assign-ip

Terraform

resource "google_sql_database_instance" "<example_resource_name>" {
  name             = "<example_resource_name>"
  region           = "<example_region>"
  database_version = "POSTGRES_14"

  settings {
    tier = "db-f1-micro"

    ip_configuration {
      ipv4_enabled    = false  # Critical: disables public IP
      private_network = "projects/<example_project_id>/global/networks/<example_resource_name>"  # Critical: enables private IP on the specified VPC
    }
  }
}

Other

1In Google Cloud Console, go to Cloud SQL and open <example_resource_id>
2Click Connections > Networking
3Uncheck Public IP
4Check Private IP and select your VPC network
5If prompted, click Set up connection to create private services access, then continue
6Click Save and wait for the instance to restart

Check Code

from prowler.lib.check.models import Check, Check_Report_GCP
from prowler.providers.gcp.services.cloudsql.cloudsql_client import cloudsql_client


class cloudsql_instance_private_ip_assignment(Check):
    def execute(self) -> Check_Report_GCP:
        findings = []
        for instance in cloudsql_client.instances:
            report = Check_Report_GCP(metadata=self.metadata(), resource=instance)
            report.status = "PASS"
            report.status_extended = f"Database Instance {instance.name} does not have private IP assignments."
            for address in instance.ip_addresses:
                if address["type"] != "PRIVATE":
                    report.status = "FAIL"
                    report.status_extended = (
                        f"Database Instance {instance.name} has public IP assignments."
                    )
                    break
            findings.append(report)

        return findings