Sign and upload a server certificate

When you create a database cluster, a server certificate that is signed by the default GDC CA will be generated and configured for use by your database server. To sign and upload a certificate for your database that is issued by your own PKI, perform the following procedure. Your organization's default issuer must be in BYO certificate mode to use this feature.

API

  1. After you have created the database cluster and it is ready, save the generated certificate signing request as a file.

    kubectl get certificate.pki.security.gdc.goog \
    dbs-DBENGINE_SHORT_NAME-cert-request-DBCLUSTER_NAME \
    -n USER_PROJECT -o jsonpath='{.status.byoCertStatus.csrStatus.csr}' \
    | base64 -d > DBCLUSTER_NAME.csr
    
  2. Create a CSR extensions file containing the SANs for your database cluster.

    export SAN=$(openssl req -in DBCLUSTER_NAME.csr -noout -text | grep 'DNS:' | sed -s 's/^[ ]*//')
    
    echo "keyUsage=digitalSignature,keyEncipherment
    extendedKeyUsage=serverAuth,clientAuth
    subjectAltName=${SAN:?}" > DBCLUSTER_NAME-csr.ext
    
  3. Using the CSR and extension file, generate the certificate signed by your CA. The code sample uses openssl but this step can be completed with other tools.

    openssl x509 -req -in DBCLUSTER_NAME.csr -days 365 \
    -CA CA_CERTIFICATE_FILE -CAkey CA_PRIVATE_KEY_FILE \
    -CAcreateserial -extfile DBCLUSTER_NAME-csr.ext  \
    -out DBCLUSTER_NAME-signed.crt
    
  4. Update the certificate resource with the signed certificate and CA certificate.

    echo "spec:
      byoCertificate:
        certificate: $(base64 -w0 DBCLUSTER_NAME-signed.crt)
        ca: $(base64 -w0 CA_CERTIFICATE_FILE)" > patch.txt
    
    kubectl patch certificate.pki.security.gdc.goog \
    dbs-DBENGINE_SHORT_NAME-cert-request-DBCLUSTER_NAME \
    -n USER_PROJECT --patch-file patch.txt --type='merge'
    
  5. Verify that the certificate has reached a ready state after the upload.

    kubectl get certificate.pki.security.gdc.goog \
    dbs-DBENGINE_SHORT_NAME-cert-request-DBCLUSTER_NAME \
    -n USER_PROJECT -o json | jq -r ' .status.conditions[] | select( .type as $id | "Ready" | index($id))'
    

    The output should be similar to the following:

    {
      "lastTransitionTime": "2024-05-03T08:42:10Z",
      "message": "Certificate is issued",
      "observedGeneration": 2,
      "reason": "Issued",
      "status": "True",
      "type": "Ready"
    }
    
  6. Only if you are using an Oracle database, stop and restart the database cluster so the listener's SSL configuration is reloaded.

Replace the following:

  • DBENGINE_SHORT_NAME: the abbreviated name of the database engine. This is one of al (AlloyDB Omni), pg (PostgreSQL), or ora (Oracle).
  • DBCLUSTER_NAME: the name of the database cluster.
  • USER_PROJECT: the name of the user project where the database cluster was created.
  • CA_CERTIFICATE_FILE: the path to the database CA certificate file.
  • CA_PRIVATE_KEY_FILE: the path to the database CA private key file.