Custom CA Trust for RegScale

Connect RegScale to AWS GovCloud RDS, internal PKI, or private MSSQL without disabling certificate validation

๐Ÿ“‹ Table of Contents

๐Ÿšจ What this guide solves

If RegScale fails at startup with a SQL pre-login handshake error such as:

A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught) ---> System.Security.Authentication.AuthenticationException: Certificate failed chain validation. Error(s): 'unable to get local issuer certificate, [Status: PartialChain]'.

your SQL Server is presenting a certificate signed by a Certificate Authority (CA) that is not in the container's default trust store. Common cases:

โš ๏ธ TrustServerCertificate=True is not a real fix.
  • It is commonly blocked by environment-level compliance policy in production (FedRAMP, IL5, internal governance) โ€” and rightly so, it disables certificate validation entirely.
  • It does not always silence the error in newer Microsoft.Data.SqlClient versions when chain validation is enforced upstream.

The proper fix is to add the missing CA certs to the pod's trust store. As of chart version 3.1.9, the chart supports this directly via app.extraCATrust.

โš™๏ธ How it works

When app.extraCATrust.enabled: true:

  1. You create a ConfigMap (or Secret) in the RegScale namespace that contains one or more PEM-encoded CA certificate files.
  2. The chart adds an init container to the RegScale pod that reads the image's existing system CA bundle, appends every PEM from your resource, and writes the merged bundle to a shared emptyDir.
  3. The main RegScale container starts with SSL_CERT_FILE=/etc/ssl/custom/ca-bundle.pem, which .NET / OpenSSL respect for TLS chain validation.
The pod still runs with readOnlyRootFilesystem: true and runAsNonRoot: true. No image rebuild is required.

๐Ÿ“‹ Prerequisites

  • RegScale chart 3.1.9 or later.
  • kubectl access to the RegScale namespace.
  • The PEM bundle for your database's CA chain.

1 Get the CA bundle

AWS GovCloud RDS (us-gov-east-1 example)

curl -fLO https://truststore.pki.us-gov-west-1.rds.amazonaws.com/us-gov-east-1/us-gov-east-1-bundle.pem

For other GovCloud regions, replace us-gov-east-1 in the URL with your region. The AWS-published bundle includes the full intermediate chain โ€” that's exactly what's needed.

AWS commercial RDS

curl -fLO https://truststore.pki.rds.amazonaws.com/<region>/<region>-bundle.pem # Example: curl -fLO https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem

Internal PKI / on-prem MSSQL

Obtain the root CA (and any intermediates) from your security/PKI team as a PEM file. If you have a .cer or .crt in DER format, convert it:

openssl x509 -inform der -in your-ca.cer -out your-ca.pem

2 Create the ConfigMap or Secret

Pick one โ€” ConfigMap is the most common choice for public AWS RDS roots.

Option A โ€” ConfigMap (recommended)

kubectl -n <regscale-namespace> create configmap rds-gov-ca \ --from-file=rds-gov-ca.pem=us-gov-east-1-bundle.pem

You can include multiple files by passing --from-file more than once. Every file in the resource is appended to the bundle, so include only certs you trust.

Option B โ€” Secret

Use this if your security policy mandates secrets for CA material (rare for public roots, common for internal PKI):

kubectl -n <regscale-namespace> create secret generic rds-gov-ca \ --from-file=rds-gov-ca.pem=us-gov-east-1-bundle.pem

3 Update your values

Add to your RegScale values file (or --set flags):

app: extraCATrust: enabled: true configMapName: rds-gov-ca # If you used a Secret instead, use: # secretName: rds-gov-ca
Set exactly one of configMapName or secretName. The chart will refuse to render if both are set, or if enabled: true with neither.

Keep your connection string with TrustServerCertificate=False:

secrets: sqlConnectionString: | Server=tcp:<rds-endpoint>,1433; Initial Catalog=REGSCALE; User ID=<user>; Password=<password>; Encrypt=True; TrustServerCertificate=False; Connection Timeout=30;

Real chain validation will now succeed because your DB's CA is in the trust bundle the pod uses.

4 Deploy / upgrade

helm upgrade --install regscale regscale/regscale \ -n <regscale-namespace> \ -f my-values.yaml

โœ… Verification

After the rollout, confirm the init container ran successfully:

kubectl -n <regscale-namespace> logs <pod> -c build-ca-trust

Expected output (cert count will vary by image and how many PEMs you added):

merged 142 certs into /trust/ca-bundle.pem

Then confirm the main container is past the pre-login handshake:

kubectl -n <regscale-namespace> logs <pod> -c regscale-app | grep -iE 'migration|handshake|chain'
You should see migration progress messages and no PartialChain / pre-login handshake errors.

๐Ÿ” Rotating the CA bundle

When AWS rotates RDS CA certificates (or your internal PKI rolls a new root), update the ConfigMap and restart the pods:

# Refresh the PEM curl -fLO https://truststore.pki.us-gov-west-1.rds.amazonaws.com/us-gov-east-1/us-gov-east-1-bundle.pem # Replace the ConfigMap atomically kubectl -n <regscale-namespace> create configmap rds-gov-ca \ --from-file=rds-gov-ca.pem=us-gov-east-1-bundle.pem \ --dry-run=client -o yaml | kubectl apply -f - # Restart RegScale kubectl -n <regscale-namespace> rollout restart deployment/<release>-regscale-app

You do not need to change values or re-run helm upgrade unless the ConfigMap name changes.

๐Ÿ” Troubleshooting

SymptomCause / fix
helm template fails: "app.extraCATrust.enabled is true but neither ... is set" You set enabled: true but forgot configMapName / secretName. Provide one.
helm template fails: "set either configMapName or secretName, not both" Pick one.
Init container build-ca-trust in Error state with "no system CA bundle found" The container image doesn't have a CA bundle in any of the standard paths (/etc/ssl/certs/ca-certificates.crt, /etc/pki/tls/certs/ca-bundle.crt, /etc/ssl/cert.pem). Contact RegScale support โ€” the base image is missing ca-certificates.
merged 1 certs ... (only one cert) and handshake still fails Your ConfigMap/Secret contained only one entry. Make sure the PEM file actually includes the full chain โ€” open it in a text editor and confirm multiple -----BEGIN CERTIFICATE----- blocks.
Handshake still fails after init container reports many certs The CA file you mounted is for a different region/environment than your DB endpoint. Re-download from the URL matching your RDS region.
Main container still throws PartialChain Your image's .NET version may not honor SSL_CERT_FILE. Contact RegScale support โ€” a follow-up overlay of the OS bundle path can be added.

๐Ÿ”’ Security notes

๐Ÿ“š Related

RegScale Helm Repository  ยท  AWS Setup  ยท  Azure Setup