TLS and Custom CA
Goal
Trust an internal or self-signed CA for OCM registry traffic without disabling TLS verification — or, as a last resort for local dev registries, opt out of verification for a specific host.
Prerequisites
- OCM CLI installed
- PEM-encoded CA certificate for the registry (for the
SSL_CERT_FILEpath)
Steps
Trust a private CA via OCM configuration (recommended)
Set
rootCAsPEM(inline PEM bundle) orrootCAsPEMFile(path) in thehttp.config.ocm.software/v1alpha1config. These certificates are appended to the system trust pool, so public registries keep verifying while your internal CA is also trusted. Scope it globally or to a single host — the same setting reaches self-hosted OCI registries, Helm repositories, and RFC 3161 timestamping servers.type: generic.config.ocm.software/v1 configurations: - type: http.config.ocm.software/v1alpha1 # Global: trust this CA for every host. rootCAsPEMFile: /etc/ocm/corp-ca.pem hosts: # Per-host: trust an internal TSA's serving certificate only here. "timestamp.corp:8443": rootCAsPEMFile: /etc/ocm/internal-tsa-ca.pemAdditive, unlike SSL_CERT_FILErootCAsPEM/rootCAsPEMFileare added to the system roots, so you do not need to concatenate the system bundle.rootCAsPEMtakes precedence overrootCAsPEMFile, and both are ignored wheninsecureSkipVerifyistrue. An invalid or unreadable bundle fails requests closed rather than silently falling back to system trust.Alternatively, trust a private CA via environment variables
The OCM CLI uses Go’s standard
crypto/tlsstack; the system root CA pool is consulted automatically. To trust an additional internal CA, pointSSL_CERT_FILEand/orSSL_CERT_DIRat your bundle. TLS verification stays on — the CLI just learns about an extra root.# Single PEM bundle — covers most internal-CA setups. export SSL_CERT_FILE=/etc/ocm/corp-ca.pem ocm get cv registry.corp/my-org//ocm.software/demos/podinfo:6.8.0# Multiple bundles — point at a directory of *.pem / *.crt files. export SSL_CERT_DIR=/etc/ocm/ca.d ocm get cv registry.corp/my-org//ocm.software/demos/podinfo:6.8.0Replacement, not mergeEach variable replaces the corresponding built-in default list inside Go’s loader (
crypto/x509’sloadOnDiskRoots).SSL_CERT_FILEreplaces the built-in list of fallback bundle paths (/etc/ssl/certs/ca-certificates.crt,/etc/pki/tls/certs/ca-bundle.crt, …).SSL_CERT_DIRreplaces the built-in list of fallback directories (/etc/ssl/certs,/etc/pki/tls/certs).Because the file and directory channels are independent, setting only one of the two leaves the other channel pulling in system roots — on a typical Debian/Ubuntu host
SSL_CERT_FILE=/etc/ocm/corp-ca.pemalone still trusts public registries. Setting both disables all system-root fallbacks; only your custom CAs are trusted. Public registries then fail withx509: certificate signed by unknown authority.To keep both your private CA and the system roots, concatenate them:
cat /etc/ssl/certs/ca-certificates.crt /etc/ocm/corp-ca.pem \ > /etc/ocm/combined-ca.pem export SSL_CERT_FILE=/etc/ocm/combined-ca.pemOr drop both into a directory:
mkdir -p /etc/ocm/ca.d cp /etc/ssl/certs/ca-certificates.crt /etc/ocm/ca.d/system.pem cp /etc/ocm/corp-ca.pem /etc/ocm/ca.d/corp.pem export SSL_CERT_DIR=/etc/ocm/ca.dPlatform differences. On macOS and Windows, Go normally delegates verification to the platform trust store (Keychain / CryptoAPI). Setting either
SSL_CERT_FILEorSSL_CERT_DIRswitches Go to its pure-Go on-disk loader and bypasses the platform store entirely. To re-enable the platform store and ignore the env vars, setGODEBUG=x509sslcertoverrideplatform=0and install the corp CA into the platform store instead.Disable TLS verification for a local or development registry
When a local registry uses a self-signed certificate that you cannot or do not want to trust via a CA bundle, use
insecureSkipVerify. Always scope it to the specific host:type: generic.config.ocm.software/v1 configurations: - type: http.config.ocm.software/v1alpha1 hosts: "registry.kind.local:5001": insecureSkipVerify: trueinsecureSkipVerify: truedisables certificate chain and hostname checks — connections become vulnerable to active man-in-the-middle attacks. Never enable this against a public registry or in production. OCM logs a warning at startup and on the first request to each new host whenever this is active.Prefer
SSL_CERT_FILE/SSL_CERT_DIRoverinsecureSkipVerifywhenever the registry has a real certificate — even a self-signed one — because TLS verification stays active and the CLI will still detect tampered or expired certs. Reach forinsecureSkipVerifyonly when you have no certificate to pin against (e.g. a barekindcluster with no cert at all).
Troubleshooting
x509: certificate signed by unknown authority
The registry’s certificate is signed by a CA not in the system trust store. Fix in order of preference:
- Set
rootCAsPEM/rootCAsPEMFilein the OCM HTTP config — additive to the system roots, scoped globally or per host, TLS verification stays enabled. - Point
SSL_CERT_FILEat a PEM bundle containing the issuing CA (replaces the built-in bundle path list; see the caution above). - Install the CA into the system trust store so all tools on the machine accept it.
- Set
insecureSkipVerify: truefor that host only as a last resort.
SSL_CERT_FILE is set but the registry still fails verification
Common causes:
- The variable was set in a different shell or after the OCM process started.
- The PEM bundle contains the server certificate rather than its issuing CA.
SSL_CERT_DIRpoints at files without.pem,.crt, or.cerextensions.- The hostname in the URL does not match a Subject Alternative Name on the cert — trusting the CA does not bypass hostname verification.
Verify the chain:
openssl s_client -connect host:port -showcertsRun OCM with --loglevel debug — a TLS error reports the leaf cert subject
(hostname mismatch) versus the issuer (chain validation failure).
Setting SSL_CERT_FILE breaks public registries
Both env vars were set and the custom bundle contains only the corp CA, so public CAs disappeared from the trust pool. Concatenate the system bundle:
cat /etc/ssl/certs/ca-certificates.crt /etc/ocm/corp-ca.pem \
> /etc/ocm/combined-ca.pem
export SSL_CERT_FILE=/etc/ocm/combined-ca.pemOn macOS / Windows: install the corp CA into the platform store and set
GODEBUG=x509sslcertoverrideplatform=0 to re-enable the platform verifier.
WARN msg="HTTP transport built with InsecureSkipVerify=true" at startup
This is informational — OCM logs the warning whenever TLS verification is
disabled. If unexpected, check whether insecureSkipVerify: true is set at
the global level rather than under a specific host entry.
Reference
HTTP Client Configuration Reference — TLS Trust
Related
- Per-Host Overrides — scope
insecureSkipVerifyto specific registries - HTTP Timeouts — set timeouts alongside TLS settings