# Custom CA Certificates (OpenSSL)

LLMS index: [llms.txt](https://hummingbird-project.io/llms.txt) | Full content: [llms-full.txt](https://hummingbird-project.io/llms-full.txt)

---

## Overview

You can configure OpenSSL-based container images (curl, nginx, etc.) to trust custom Certificate Authority (CA) certificates for TLS connections.

There are two approaches for custom CAs depending on your needs:

1. **Custom bundle file** - Replace system CAs entirely with your own bundle
2. **Derived image** - Build a new image with merged trust store

## Approach 1: Custom Bundle File

Use this when you want to trust **only** your custom CAs and block all default CAs. This is a common case with [OpenShift's custom PKI bundle][os-custom-pki].

Mount your CA bundle to `/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem`:

### Custom bundle with Podman

```bash
podman run --rm \
  -v /path/to/ca.crt:/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem:ro,Z \
  registry.access.redhat.com/hi/curl https://your-server/
```

### Custom bundle with Kubernetes

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-ca-bundle
data:
  tls-ca-bundle.pem: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    ... more certificates if needed ...
---
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: app
    image: registry.access.redhat.com/hi/curl
    volumeMounts:
    - name: custom-ca
      mountPath: /etc/pki/ca-trust/extracted/pem
      readOnly: true
  volumes:
  - name: custom-ca
    configMap:
      name: custom-ca-bundle
```

### Custom bundle on OpenShift with CA injection

On OpenShift, the cluster admin may have already added your organization's CA certificates to the cluster-wide trust store. You can use OpenShift's automatic CA injection feature to make these certificates available to your pods.

Create a ConfigMap with the `config.openshift.io/inject-trusted-cabundle=true` label. OpenShift will automatically populate it with the cluster CA bundle as a key named `ca-bundle.crt`:

```yaml
# OpenShift will inject a "ca-bundle.crt" into this automatically
apiVersion: v1
kind: ConfigMap
metadata:
  name: trusted-ca
  labels:
    config.openshift.io/inject-trusted-cabundle: "true"
---
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: app
    image: registry.access.redhat.com/hi/curl
    volumeMounts:
    - name: trusted-ca
      mountPath: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
      subPath: ca-bundle.crt
      readOnly: true
  volumes:
  - name: trusted-ca
    configMap:
      name: trusted-ca
```

The key detail is using `subPath: ca-bundle.crt` to mount OpenShift's injected file to the correct location (`tls-ca-bundle.pem`) that OpenSSL expects.

See the [Configuring a custom PKI][os-custom-pki] OpenShift documentation for details on cluster-wide CA configuration.

[os-custom-pki]: https://docs.redhat.com/en/documentation/openshift_container_platform/4.21/html/configuring_network_settings/configuring-a-custom-pki

## Approach 2: Derived Image

Use this approach when you need to trust both your custom CA and the image's builtin default CAs. This creates a new image with a merged trust store with the `trust anchor` command.

Create a multi-stage Containerfile with your `ca.crt` in the build context. This example derives from the `curl` image:

```dockerfile
FROM registry.access.redhat.com/hi/curl:latest-builder AS builder

USER root
COPY ca.crt /tmp/
RUN trust anchor /tmp/ca.crt

FROM registry.access.redhat.com/hi/curl:latest
COPY --from=builder /etc/pki /etc/pki
```

Build and use your custom image:

```bash
podman build -t my-curl-with-ca .
podman run --rm my-curl-with-ca https://your-server/
```
