Skip to main content

Secure Database Connectivity with SSL

Last updated on

This document provides a comprehensive guide to configuring databases with SSL, including secret and delegate configurations, setting up for JDBC test connections, and pipeline permissions. It covers the necessary steps to set up and manage certificates for secure communication between database and other services.

1. SSL Support by Integration Type

SSL handling differs based on how Database DevOps interacts with external systems. Use the table below to confirm support and configuration scope.

Functionality TypeSSL SupportTransport LayerCert ManagementNotes
Git (Schema Cloning)✅ YesHTTPSMounted certs (/etc/ssl/certs/ca-bundle.crt)More Info
Artifactory (Schema Cloning)❌ NoHTTPN/ASSL not supported for Artifactory-based schema cloning
Database Connections (JDBC)✅ YesJDBC over SSLRequires importing DB certs into truststoreSee Connector Setup Guide
Reference Architecture

Harness Database DevOps reuses the same Kubernetes build infrastructure mechanisms as Harness CI for certificate handling.

If you are unfamiliar with certificate mounting in Kubernetes build pods, review: 👉 Configure a Kubernetes build farm to use self-signed certificates

2. Prepare Required Certificates

Ensure you have the following files available locally:

  • CA Bundle - ca.crt (commonly contains ca.crt, used by both client and server)

    Important Notes
    • In most environments, a single CA signs both client and server.
    • If separate CAs are used, both must be included in the CA bundle.
  • Client Certificate - client.crt and client.key needs to be manually created by the user. Learn how to Generate client certificates. Certificates are mounted once on the delegate and selectively injected into build pods using CI_MOUNT_VOLUMES.

note

Minimum versions

  • db-devops-service - 1.32.x
  • drone-liquibase - plugins/drone-liquibase:1.1.0-4.27
  • drone-liquibase-mongo - plugins/drone-liquibase:1.1.0-4.27-mongo
  • drone-liquibase-spanner - plugins/drone-liquibase:1.1.0-4.27-spanner

3. Create the Kubernetes Secret

Create a Kubernetes secret containing all certificates.

kubectl create secret -n <namespace> generic dbops-ssl-secret \
--from-file=ca.bundle \
--from-file=client.crt \
--from-file=client.key
note

Ensure that the key names (ca.bundle, client.crt, client.key) match exactly with what your database client expects. If your database client expects ca.crt instead of ca.bundle:

kubectl create secret -n <namespace> generic dbops-ssl-secret \
--from-file=ca.crt=ca.bundle \
--from-file=client.crt \
--from-file=client.key

4. Mount Certificates into the Delegate

  1. Modify the delegate manifest file to include a volume mount. Add the following YAML under spec.template.spec.containers
volumeMounts:
- mountPath: /opt/harness-delegate/ca-bundle/
name: custom-certs
readOnly: true
  1. Add the following under spec.template.spec. Add the secret name with the value you used when you created the kubernetes secret.
securityContext:
fsGroup: 1001
volumes:
- name: custom-certs
secret:
secretName: dbops-ssl-secret
defaultMode: 0440

dbops-ssl-secret is the name of the secret created in the previous step. Ensure that the secret name matches.

  1. Set Environment Variables
  • ADDITIONAL_CERTS_PATH ensures the delegate trusts the CA
  • CI_MOUNT_VOLUMES injects certs into ephemeral build pods
  • DESTINATION_CA_PATH cannot be used because multiple certs must be mounted independently
warning

Do not use DESTINATION_CA_PATH when using CI_MOUNT_VOLUMES to mount certificates into build pods. Instead, use the ADDITIONAL_CERTS_PATH environment variable to specify the path to the certificates on the delegate.

Add the following environment variables to the delegate:

- name: ADDITIONAL_CERTS_PATH
value: "/opt/harness-delegate/ca-bundle/ca.bundle"

- name: CI_MOUNT_VOLUMES
value: "/opt/harness-delegate/ca-bundle/ca.bundle:/etc/ssl/certs/dbops/root_ca.crt,/opt/harness-delegate/ca-bundle/client.key:/etc/ssl/certs/dbops/client.key,/opt/harness-delegate/ca-bundle/client.crt:/etc/ssl/certs/dbops/client.crt"
note

When using CI_MOUNT_VOLUMES, the mounted file paths must be:

  • /etc/ssl/certs/dbops/root_ca.crt
  • /etc/ssl/certs/dbops/client.crt
  • /etc/ssl/certs/dbops/client.key Also, you must set the ADDITIONAL_CERTS_PATH environment variable when using CI_MOUNT_VOLUMES.

Why this matters ?

  • ADDITIONAL_CERTS_PATH ensures the delegate trusts the database CA
  • CI_MOUNT_VOLUMES injects certs into ephemeral build pods
  • DESTINATION_CA_PATH is not used because multiple certs must be mounted independently Restart the delegate after applying changes.

5. Enable JDBC SSL Truststore Support

Add the following to the delegate environment:

- name: INIT_SCRIPT
value: |-

openssl pkcs12 -export -in /opt/harness-delegate/ca-bundle/client.crt -inkey /opt/harness-delegate/ca-bundle/client.key -out client.p12 -name client_pkcs12 -password pass:changeit

keytool -importkeystore -destkeystore $JAVA_HOME/lib/security/jssecacerts -srckeystore client.p12 -srcstoretype PKCS12 -alias client_pkcs12 -storepass changeit -srcstorepass changeit -noprompt

What this does ?

  • Combines client cert and key into a PKCS12 file
  • Imports it into the Java truststore
  • Enables JDBC SSL authentication during test connections
note
  • INIT_SCRIPT is required because the JDBC Test Connection runs inside the delegate container.
  • The delegate automatically imports ca.bundle into the default trust store ($JAVA_HOME/lib/security/cacerts).
  • Learn more: Override trust store for delegates

Verfication

If the setup is successful, logs in the step will look like below: Verfication Logs

Troubleshoot Common Issues

IssueLikely CauseResolution
SSL handshake failureCA not trustedVerify ADDITIONAL_CERTS_PATH
JDBC test failsClient cert not importedCheck INIT_SCRIPT
Works locally, fails in pipelineCerts not mounted in build podVerify CI_MOUNT_VOLUMES
Changes not appliedDelegate not restartedRestart delegate

References