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. Clone
Harness Database DevOps supports multiple source types for schema cloning and connecting to databases. SSL support varies based on the source type and integration method. The table below outlines SSL compatibility and configuration requirements for each supported source:
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 |
2. Pre-requisites
Before proceeding, ensure you have the following components and versions in place:
- CA Bundle -
ca.crt
(commonly containsca.crt
, used by both client and server)- Generate CA certificate
- Manage CA bundles and secrets
Important NoteIn most setups, the same CA signs both ends of the connection. If your environment uses distinct CAs for client and server, ensure both are trusted in the CA bundle.
- Client Certificate -
client.crt
andclient.key
needs to be manually created by the user.- Learn how to Generate client certificates
CI_MOUNT_VOLUMES
andADDITIONAL_CERTS_PATH
delegate environment variables- We cannot use
DESTINATION_CA_PATH
since we need to mount different certificates to the build pod
- We cannot use
- Review supported configurations for your database type: Set up Connectors for Database DevOps
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. Secret Configuration
Create a SSL Kubernetes secret with all certs:
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. For example, if the client expects ca.crt
, rename the file accordingly before creating the secret.
kubectl create secret -n <namespace> generic dbops-ssl-secret \
--from-file=ca.crt=ca.bundle \
--from-file=client.crt \
--from-file=client.key
4. Delegate Configuration
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: 400
dbops-ssl-secret
is the name of the secret created in the previous step. Ensure that the secret name matches.
- Set Environment Variables
- 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.key
Also, you must set theADDITIONAL_CERTS_PATH
environment variable when usingCI_MOUNT_VOLUMES
.
5. JDBC Test Connection
- 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
The INIT_SCRIPT
environment variable in the Harness Delegate is used to execute a startup script that generates client.p12
from client.crt
and client.key
and imports it into java keystore $JAVA_HOME/lib/security/jssecacerts
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
6. Pipeline Permissions
To import keys into the system trust store, the DB step must have access to the build pod. For example, If you need to run the step as root (e.g., for ApplySchema
), set runAsUser: 0
in your step config:
# spec.template.spec.containers.image.securityContext
runAsUser: "0"
This ensures the step has the necessary permissions to update keystores.
Verfication
If the setup is successful, logs in the step will look like below: