Skip to content

Mounting the CA bundle

Tested with: cert-manager 1.16 · trust-manager 0.12 · Kubernetes 1.31

The gateway’s certificate is publicly trusted, so Go, Node, .NET, JVM and most Ruby drivers verify it from the OS bundle in the container image. libpq-based drivers (psql, psycopg, Ruby pg, PHP PDO pgsql, Npgsql with Root Certificate) and MySQL clients with VERIFY_IDENTITY need a file path. Mount it; do not bake it into images, because the bundle rotates.

shell
zb api GET /v1/orgs/{org}/ca.pem > databasezy-ca.pem
kubectl -n app create configmap databasezy-ca --from-file=ca.crt=databasezy-ca.pem \
--dry-run=client -o yaml | kubectl apply -f -
deployment (excerpt)
env:
- name: PGSSLMODE
value: verify-full
- name: PGSSLROOTCERT
value: /etc/databasezy/ca.crt
volumeMounts:
- { name: databasezy-ca, mountPath: /etc/databasezy, readOnly: true }
volumes:
- name: databasezy-ca
configMap: { name: databasezy-ca }

The intermediate rotates on the dates published under Settings → Certificates; we email org admins 30 days before. The published bundle always contains both the current and the next intermediate, so refreshing it once in that window is enough. A CronJob that fetches the bundle with zb api and updates the ConfigMap keeps everything current:

cronjob-refresh-ca.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: refresh-databasezy-ca
namespace: cert-manager
spec:
schedule: "0 3 * * 1"
jobTemplate:
spec:
template:
spec:
serviceAccountName: refresh-databasezy-ca # RBAC: get/update configmaps in this namespace
restartPolicy: OnFailure
containers:
- name: refresh
image: ghcr.io/zerobase/zb:0.1
envFrom:
- secretRef: { name: databasezy-api } # ZB_API_KEY and ZB_ORG
command: ["sh", "-c"]
args:
- zb api GET '/v1/orgs/{org}/ca.pem' > /tmp/ca.crt && kubectl -n cert-manager create configmap databasezy-ca-source
--from-file=ca.crt=/tmp/ca.crt --dry-run=client -o yaml | kubectl apply -f -