Configure SSL/TLS certificates

This page describes how to configure an instance to use SSL/TLS. You can also learn more about how Cloud SQL uses self-managed SSL/TLS certificates to securely connect to Cloud SQL instances.

Overview

Cloud SQL creates a server certificate (server-ca.pem) automatically when you create your instance. We recommend that you enforce all connections to use SSL/TLS.

To validate client/server identity using SSL/TLS certs, you need to create a client certificate and download the certificates to your PostgreSQL client host machine.

When you enforce SSL for an instance, the instance does not require a restart. However, changes to SSL/TLS certificates might result in an automatic restart of the instance and can incur downtime.

A change to SSL mode configuration applies only to new connections. If you enforce SSL and your instance has existing unencrypted connections, then the connections stay connected and unencrypted. To close any unencrypted connections and enforce SSL on all connections, you must restart your instance.

Enforce SSL/TLS encryption

You can use the SSL mode setting to enforce SSL encryption in the following ways:

  • Allow both non-SSL/non-TLS and SSL/TLS connections. The client certificate isn't verified for SSL/TLS connections. This is the default.

  • Only allow connections encrypted with SSL/TLS. The client certificate isn't verified for SSL connections.

  • Only allow connections encrypted with SSL/TLS and with valid client certificates.

If you select Allow non-SSL/non-TLS and SSL/TLS connections for your Cloud SQL instance, SSL/TLS connections are accepted, as well as unencrypted and unsecure connections. If you do not require SSL/TLS for all connections, unencrypted connections are still allowed. For this reason, if you are accessing your instance using public IP, we strongly recommend that you enforce SSL for all connections.

You can connect either directly to instances by using SSL/TLS certificates, or you can connect by using the Cloud SQL Auth Proxy or Cloud SQL Connectors. If you connect by using Cloud SQL Auth Proxy or Cloud SQL Connectors, then the connections are automatically encrypted with SSL/TLS. With Cloud SQL Auth Proxy and Cloud SQL Connectors, client and server identities are also automatically verified regardless of the SSL mode setting.

To enable requiring SSL/TLS, do the following:

Console

  1. In the Google Cloud console, go to the Cloud SQL Instances page.

    Go to Cloud SQL Instances

  2. To open the Overview page of an instance, click the instance name.
  3. Click Connections from the SQL navigation menu.
  4. Select the Security tab.
  5. Select one of the following:
    • Allow unencrypted network traffic (not recommended)
    • Allow only SSL connections. This option only allows connections using SSL/TLS encryption. Certificates aren't validated.
    • Require trusted client certificates. This option only allows connections from clients that use a valid client certificate and are SSL encrypted. If a client or user connects using IAM database authentication, then they must use either the Cloud SQL Auth Proxy or Cloud SQL Connectors to enforce client identity verification.

gcloud

   gcloud sql instances patch INSTANCE_NAME \
   --ssl-mode=SSL_ENFORCEMENT_MODE
  

Replace SSL_ENFORCEMENT_MODE with one of the following options:

  • ALLOW_UNENCRYPTED_AND_ENCRYPTED allows non-SSL/non-TLS and SSL/TLS connections. For SSL connections, the client certificate is not verified. This is the default value.
  • ENCRYPTED_ONLY only allows connections encrypted with SSL/TLS. The client certificate isn't verified for SSL connections.
  • TRUSTED_CLIENT_CERTIFICATE_REQUIRED only allows connections encrypted with SSL/TLS and with valid client certificates. If a client or user connects using IAM database authentication, then they must use either the Cloud SQL Auth Proxy or Cloud SQL Connectors to enforce client identity verification.
For more information, see Settings for Cloud SQL for PostgreSQL.

Terraform

To enforce SSL/TLS encryption, use a Terraform resource:

resource "google_sql_database_instance" "postgres_instance" {
  name             = "postgres-instance"
  region           = "asia-northeast1"
  database_version = "POSTGRES_14"
  settings {
    tier = "db-custom-2-7680"
    ip_configuration {
      # The following SSL enforcement options only allow connections encrypted with SSL/TLS and with
      # valid client certificates. Please check the API reference for other SSL enforcement options:
      # https://cloud.google.com/sql/docs/postgres/admin-api/rest/v1beta4/instances#ipconfiguration
      require_ssl = "true"
      ssl_mode    = "TRUSTED_CLIENT_CERTIFICATE_REQUIRED"
    }
  }
  # set `deletion_protection` to true, will ensure that one cannot accidentally delete this instance by
  # use of Terraform whereas `deletion_protection_enabled` flag protects this instance at the GCP level.
  deletion_protection = false
}

Apply the changes

To apply your Terraform configuration in a Google Cloud project, complete the steps in the following sections.

Prepare Cloud Shell

  1. Launch Cloud Shell.
  2. Set the default Google Cloud project where you want to apply your Terraform configurations.

    You only need to run this command once per project, and you can run it in any directory.

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    Environment variables are overridden if you set explicit values in the Terraform configuration file.

Prepare the directory

Each Terraform configuration file must have its own directory (also called a root module).

  1. In Cloud Shell, create a directory and a new file within that directory. The filename must have the .tf extension—for example main.tf. In this tutorial, the file is referred to as main.tf.
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. If you are following a tutorial, you can copy the sample code in each section or step.

    Copy the sample code into the newly created main.tf.

    Optionally, copy the code from GitHub. This is recommended when the Terraform snippet is part of an end-to-end solution.

  3. Review and modify the sample parameters to apply to your environment.
  4. Save your changes.
  5. Initialize Terraform. You only need to do this once per directory.
    terraform init

    Optionally, to use the latest Google provider version, include the -upgrade option:

    terraform init -upgrade

Apply the changes

  1. Review the configuration and verify that the resources that Terraform is going to create or update match your expectations:
    terraform plan

    Make corrections to the configuration as necessary.

  2. Apply the Terraform configuration by running the following command and entering yes at the prompt:
    terraform apply

    Wait until Terraform displays the "Apply complete!" message.

  3. Open your Google Cloud project to view the results. In the Google Cloud console, navigate to your resources in the UI to make sure that Terraform has created or updated them.

Delete the changes

To delete your changes, do the following:

  1. To disable deletion protection, in your Terraform configuration file set the deletion_protection argument to false.
    deletion_protection =  "false"
  2. Apply the updated Terraform configuration by running the following command and entering yes at the prompt:
    terraform apply
  1. Remove resources previously applied with your Terraform configuration by running the following command and entering yes at the prompt:

    terraform destroy

REST v1

  1. Before using any of the request data, make the following replacements:

    • PROJECT_ID: The project ID
    • SSL_ENFORCEMENT_MODE: Use one of the following options:
      • ALLOW_UNENCRYPTED_AND_ENCRYPTED: allows non-SSL/non-TLS and SSL/TLS connections. For SSL connections, the client certificate isn't verified. This is the default value.
      • ENCRYPTED_ONLY: only allows connections encrypted with SSL/TLS.
      • TRUSTED_CLIENT_CERTIFICATE_REQUIRED: only allows connections encrypted with SSL/TLS and with valid client certificates. If a client or user connects using IAM database authentication, then they must use either the Cloud SQL Auth Proxy or Cloud SQL Connectors to enforce client identity verification.
    • INSTANCE_ID: The instance ID

    HTTP method and URL:

    PATCH https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID

    Request JSON body:

    
    {
      "settings": {
        "ipConfiguration": {"sslMode": "SSL_ENFORCEMENT_MODE"}
      }
    }
    
    

    To send your request, expand one of these options:

    You should receive a JSON response similar to the following:

REST v1beta4

  1. Before using any of the request data, make the following replacements:

    • PROJECT_ID: The project ID
    • SSL_ENFORCEMENT_MODE: Use one of the following options:
      • ALLOW_UNENCRYPTED_AND_ENCRYPTED: allows non-SSL/non-TLS and SSL/TLS connections. For SSL connections, the client certificate isn't verified. This is the default value.
      • ENCRYPTED_ONLY: only allows connections encrypted with SSL/TLS.
      • TRUSTED_CLIENT_CERTIFICATE_REQUIRED: only allows connections encrypted with SSL/TLS and with valid client certificates. If a client or user connects using IAM database authentication, then they must use either the Cloud SQL Auth Proxy or Cloud SQL Connectors to enforce client identity verification.
    • INSTANCE_ID: The instance ID

    HTTP method and URL:

    PATCH https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID

    Request JSON body:

    
    {
      "settings": {
        "ipConfiguration": {"sslMode": "SSL_ENFORCEMENT_MODE"}
      }
    }
    
    

    To send your request, expand one of these options:

    You should receive a JSON response similar to the following:

Server certificates

Cloud SQL creates a server certificate automatically when you create your instance. As long as the server certificate is valid, you do not need to actively manage your server certificate. However, the certificate has an expiration date of 10 years; after that date, it is no longer valid, and clients are not able to establish a secure connection to your instance using that certificate. You're periodically notified that the server certificate is nearing expiration. The notifications are sent the following number of days before the expiration date: 90, 30, 10, 2, and 1.

You can get information about your server certificate, such as when it was created and when it expires, or manually create a new one.

Console

  1. In the Google Cloud console, go to the Cloud SQL Instances page.

    Go to Cloud SQL Instances

  2. To open the Overview page of an instance, click the instance name.
  3. Click Connections from the SQL navigation menu.
  4. Select the Security tab.
  5. Scroll down to the Manage server certificates section.

    You can see the expiration date of your server certificate in the table.

gcloud

  1. Get information about the service certificate:
    gcloud beta sql ssl server-ca-certs list \
    --instance=INSTANCE_NAME
    
  2. Create a server certificate:
    gcloud beta sql ssl server-ca-certs create \
    --instance=INSTANCE_NAME
    
  3. Download the certificate information to a local PEM file:
    gcloud beta sql ssl server-ca-certs list \
    --format="value(cert)" \
    --instance=INSTANCE_NAME > \
    FILE_PATH/FILE_NAME.pem
    
  4. Update all of your clients to use the new information by copying the downloaded file to your client host machines, replacing the existing server-ca.pem files.

Terraform

To provide server certificate information as an output, use a Terraform data source:

  1. Add the following to your Terraform configuration file:
       data "google_sql_ca_certs" "ca_certs" {
         instance = google_sql_database_instance.default.name
       }
    
       locals {
         furthest_expiration_time = reverse(sort([for k, v in data.google_sql_ca_certs.ca_certs.certs : v.expiration_time]))[0]
         latest_ca_cert           = [for v in data.google_sql_ca_certs.ca_certs.certs : v.cert if v.expiration_time == local.furthest_expiration_time]
       }
    
       output "db_latest_ca_cert" {
         description = "Latest CA certificate used by the primary database server"
         value       = local.latest_ca_cert
         sensitive   = true
       }
       
  2. To create the server-ca.pem file, run the following command:
       terraform output db_latest_ca_cert > server-ca.pem
       

Client certificates

Create a new client certificate

You can create up to 10 client certificates for each instance. To create client certificates, you must have the Cloud SQL Admin IAM role.

Here are some important things to know about client certificates:

  • If you lose the private key for a certificate, you must create a new one; the private key cannot be recovered.
  • By default, the client certificate has an expiration date of 10 years.
  • You are not notified when client certificates are nearing expiration.
  • Your Cloud SQL instance must be in the running state to create a SSL certificate.

Console

  1. In the Google Cloud console, go to the Cloud SQL Instances page.

    Go to Cloud SQL Instances

  2. To open the Overview page of an instance, click the instance name.
  3. Click Connections from the SQL navigation menu.
  4. Select the Security tab.
  5. Click Create client certificate.
  6. In the Create a client certificate dialog box, add a unique name.
  7. Click Create.
  8. In the first section of the New SSL certificate created dialog box, click Download client-key.pem to download the private key to a file named client-key.pem.
  9. In the second section, click Download client-cert.pem to download the client certificate to a file named client-cert.pem.
  10. In the third section, click Download server-ca.pem to download the server certificate to a file named server-ca.pem.
  11. Click Close.

gcloud

  1. Create a client certificate using the ssl client-certs create command:

    gcloud sql ssl client-certs create CERT_NAME client-key.pem \
    --instance=INSTANCE_NAME
    
  2. Retrieve the public key for the certificate you just created and copy it into the client-cert.pem file with the ssl client-certs describe command:

    gcloud sql ssl client-certs describe CERT_NAME \
    --instance=INSTANCE_NAME \
    --format="value(cert)" > client-cert.pem
    
  3. Copy the server certificate into the server-ca.pem file using the instances describe command:

    gcloud sql instances describe INSTANCE_NAME \
    --format="value(serverCaCert.cert)" > server-ca.pem
    

Terraform

To create a client certificate, use a Terraform resource:

resource "google_sql_ssl_cert" "postgres_client_cert" {
  common_name = "postgres_common_name"
  instance    = google_sql_database_instance.postgres_instance.name
}

REST v1

  1. Create an SSL/TLS certificate, giving it a unique name for this instance:

    Before using any of the request data, make the following replacements:

    • project-id: The project ID
    • instance-id: The instance ID
    • client-cert-name: The client cert name

    HTTP method and URL:

    POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id/sslCerts

    Request JSON body:

    {
      "commonName" : "client-cert-name"
    }
    

    To send your request, expand one of these options:

    You should receive a JSON response similar to the following:

  2. Copy all of the certificate contents within the quotation marks (but not the quotation marks themselves) from the response into local files as follows:
    1. Copy serverCaCert.cert into server-ca.pem.
    2. Copy clientCert.cert into client-cert.pem.
    3. Copy certPrivateKey into client-key.pem.

REST v1beta4

  1. Create an SSL/TLS certificate, giving it a unique name for this instance:

    Before using any of the request data, make the following replacements:

    • project-id: The project ID
    • instance-id: The instance ID
    • client-cert-name: The client cert name

    HTTP method and URL:

    POST https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/sslCerts

    Request JSON body:

    {
      "commonName" : "client-cert-name"
    }
    

    To send your request, expand one of these options:

    You should receive a JSON response similar to the following:

  2. Copy all of the certificate contents within the quotation marks (but not the quotation marks themselves) from the response into local files as follows:
    1. Copy serverCaCert.cert into server-ca.pem.
    2. Copy clientCert.cert into client-cert.pem.
    3. Copy certPrivateKey into client-key.pem.

At this point, you have:

  • A server certificate saved as server-ca.pem.
  • A client public key certificate saved as client-cert.pem.
  • A client private key saved as client-key.pem.
Depending on which tool you use to connect, these three items are specified in different ways. For example, when connecting using psql command-line client, these three files are the values for the sslrootcert, sslcert, and sslkey parameters in the psql connection string. For an example connection using psql client and SSL/TLS, see Connecting with psql client.

What's next