SECURITY & INFRASTRUCTURE

Fix Docker’s CA trust without upgrading your app

Browser and OS updates bring CA protections. Docker containers carry their own trust stores: update them separately.

  • Andreas Petersson
  • 2 min read

Your backend trusts certificates when it calls payment services and other APIs. The eMudhra CA compromise shows why that trust needs maintenance: an attacker with a compromised signing key and access to the traffic could impersonate those services. Updating a legacy runtime takes testing. A separate CA bundle lets you block the affected chains while keeping your tested container image.

1. Override trust in Compose

For a Linux Node.js service, save this as compose.ca.yml:

# compose.ca.yml — use your existing service name
services:
  application:
    environment:
      NODE_OPTIONS: "--use-openssl-ca"
      SSL_CERT_FILE: /run/ca-policy/ca.pem
      SSL_CERT_DIR: /run/ca-policy/empty
    volumes:
      - type: bind
        source: ./ca-policy
        target: /run/ca-policy
        read_only: true
        bind:
          create_host_path: false

Keep your tested image digest. Merge existing NODE_OPTIONSand review application-specific CA settings. This example selects Node’s OpenSSL trust store; Python, Java and other clients need their own trust configuration.

2. Build the CA bundle

On an updated host, download our Python 3 filter and a fresh Mozilla CA bundle from curl:

curl --fail --show-error --silent \
  https://curl.se/ca/cacert.pem -o public-ca.pem
python3 filter-ca-bundle.py public-ca.pem --out ca-policy

The filter removes the incident’s four published root fingerprints, validates the PEM certificates and creates ca.pem, an empty certificate directory and a checksum manifest. The empty directory closes the alternative OpenSSL directory lookup. Use a fresh output directory for each revision.

Add required, vetted private CAs with --private-ca company.pem. Keep the policy directory administrator-controlled and readable by the container. Root removal also affects legitimate services using those roots, so check your dependencies.

3. Recreate and verify

docker compose -f compose.yml -f compose.ca.yml config -q
docker compose -f compose.yml -f compose.ca.yml up -d \
  --no-deps --no-build --pull never --force-recreate application

Recreation activates the policy. Test the twelve diagnostic chains and your legitimate APIs through the actual client. Require issuer or blocked-key rejection; classify DNS failures and timeouts as inconclusive. Keep TLS verification enabled. Retain the override until a tested, updated image supplies the protection itself.

Why a backend is at risk

Your backend calls a payment API. An attacker who can redirect that traffic and present a certificate signed with a compromised CA key could impersonate the API, capture its bearer token or return forged payment results. The backend’s own certificate verifier decides whether to trust that connection.

Back to the blog