Secure Database Connectivity with SSL
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 Type | SSL Support | Transport Layer | Cert Management | Notes |
|---|---|---|---|---|
| Git (Schema Cloning) | ✅ Yes | HTTPS | Mounted certs (/etc/ssl/certs/ca-bundle.crt) | More Info |
| Artifactory (Schema Cloning) | ❌ No | HTTP | N/A | SSL not supported for Artifactory-based schema cloning |
| Database Connections (JDBC) | ✅ Yes | JDBC over SSL | Requires importing DB certs into truststore | See Connector Setup Guide |
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 containsca.crt, used by both client and server)- Generate CA certificate
- Manage CA bundles and secrets
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.crtandclient.keyneeds 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 usingCI_MOUNT_VOLUMES.
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
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
- 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
- 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.
- Set Environment Variables
ADDITIONAL_CERTS_PATHensures the delegate trusts the CACI_MOUNT_VOLUMESinjects certs into ephemeral build podsDESTINATION_CA_PATHcannot be used because multiple certs must be mounted independently
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"
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.keyAlso, you must set theADDITIONAL_CERTS_PATHenvironment variable when usingCI_MOUNT_VOLUMES.
Why this matters ?
ADDITIONAL_CERTS_PATHensures the delegate trusts the database CACI_MOUNT_VOLUMESinjects certs into ephemeral build podsDESTINATION_CA_PATHis 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
INIT_SCRIPTis required because the JDBC Test Connection runs inside the delegate container.- The delegate automatically imports
ca.bundleinto 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:

Troubleshoot Common Issues
| Issue | Likely Cause | Resolution |
|---|---|---|
| SSL handshake failure | CA not trusted | Verify ADDITIONAL_CERTS_PATH |
| JDBC test fails | Client cert not imported | Check INIT_SCRIPT |
| Works locally, fails in pipeline | Certs not mounted in build pod | Verify CI_MOUNT_VOLUMES |
| Changes not applied | Delegate not restarted | Restart delegate |