Use Python images with custom CA certificates

You can make your custom root Certificate Authority (CA) certificates available to Python images. Your application can then establish secure TLS connections to services that use certificates signed by your company’s CA.

Python libraries search for trusted certificates in different locations:

  • The built-in urllib library reads the CAs from the following locations:
    • /etc/pki/tls/cert.pem - the main CA bundle file
    • /etc/pki/tls/certs/ - a directory with hashed certificate symbolic links
  • The third-party requests library only uses the path defined in the REQUESTS_CA_BUNDLE environment variable.

    The requests library is not included in the standard Python image. If you want to use it, you must create a custom image.

Replace system CA certificates in Python images by using Podman

Use the Podman volume mount option to override the image’s Certificate Authority (CA) bundle if you require only a custom certificate bundle in a Python image. The application in your image then uses only the custom bundle.

Before you begin

  • The podman package is installed.
  • You have the CA certificate bundle in PEM format.

Procedure

When you start the container, use a bind mount to pass the certificate bundle to the container. For example:
$ podman run \
    --rm \
    --volume <path_to_certificate_bundle>.pem:/etc/pki/tls/cert.pem:ro,Z \
    --tmpfs /etc/pki/tls/certs:notmpcopyup \
    --env REQUESTS_CA_BUNDLE=/etc/pki/tls/cert.pem \
    registry.access.redhat.com/hi/python

This command mounts your CA bundle to the /etc/pki/tls/cert.pem file, sets the $REQUESTS_CA_BUNDLE environment variable to it, and blocks the directory with the hashes by overriding it with an empty tmpfs overlay.

Important:

This approach replaces the image’s built-in CA certificate bundle. If you require that your container trusts multiple CAs, ensure that all required CA certificates are part of the file that you mount to the container.

Replace system CA certificates by injecting the cluster-wide CA bundle in Python images on OpenShift Container Platform

If you require only a custom certificate bundle in a Python image, you can use an OpenShift Container Platform ConfigMap to override the image’s Certificate Authority (CA) bundle. The application in your image then uses only the custom bundle.

Before you begin

  • You have access to OpenShift Container Platform CLI.
  • The cluster administrator added the custom CA bundle to the cluster-wide proxy.
  • You have the permissions to create ConfigMaps and modify Pod specifications in the target namespace.

Procedure

  1. Display the name of the ConfigMap that contains the cluster-wide trusted certificates:
    $ oc get proxy/cluster -o jsonpath='{.spec.trustedCA.name}'
    ca-bundle
  2. Create a YAML configuration file that both defines the CA bundle and the volume mount necessary for your application to access it:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: trusted-ca
      labels:
        config.openshift.io/inject-trusted-cabundle: "true"
    ---
    apiVersion: v1
    kind: Pod
    spec:
      containers:
      - name: app
        # Use registry.access.redhat.com/hi/python if you require only urllib
        # Use your custom image with the requests library installed for both libraries
        image: registry.access.redhat.com/hi/python
        env:
        - name: REQUESTS_CA_BUNDLE
          value: /etc/pki/tls/cert.pem
        volumeMounts:
        - name: trusted-ca
          mountPath: /etc/pki/tls/cert.pem
          subPath: ca-bundle.crt
          readOnly: true
        - name: empty-certs
          mountPath: /etc/pki/tls/certs
          readOnly: true
      volumes:
      - name: trusted-ca
        configMap:
          name: trusted-ca
      - name: empty-certs
        emptyDir: {}
  3. Apply the configuration:
    $ oc apply -f <configuration_file>.yaml

Replace system CA certificates by injecting a custom CA bundle in Python images on OpenShift Container Platform

If you require only a custom certificate bundle in a Python image, you can use an OpenShift Container Platform ConfigMap to override the image’s Certificate Authority (CA) bundle. The application in your image then uses only the custom bundle.

Before you begin

  • You have access to OpenShift Container Platform CLI.
  • You have the CA certificate bundle in PEM format.
  • You have the permissions to create ConfigMaps and modify Pod specifications in the target namespace.

Procedure

  1. Create a YAML configuration file that both defines the CA bundle and the volume mount necessary for your application to access it:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: custom-ca-bundle
    data:
      cert.pem: |
        -----BEGIN CERTIFICATE-----
        <certificate>
        -----END CERTIFICATE-----
        <more_certificates_if_needed>
    ---
    apiVersion: v1
    kind: Pod
    spec:
      containers:
      - name: app
        # Use registry.access.redhat.com/hi/python if you require only urllib
        # Use your custom image with the requests library installed for both libraries
        image: registry.access.redhat.com/hi/python
        env:
        - name: REQUESTS_CA_BUNDLE
          value: /etc/pki/tls/cert.pem
        volumeMounts:
        - name: custom-ca
          mountPath: /etc/pki/tls/cert.pem
          subPath: cert.pem
          readOnly: true
        - name: empty-certs
          mountPath: /etc/pki/tls/certs
          readOnly: true
      volumes:
      - name: custom-ca
        configMap:
          name: custom-ca-bundle
      - name: empty-certs
        emptyDir: {}
  2. Apply the configuration:
    $ oc apply -f <configuration_file>.yaml

Add a custom CA bundle to Python images by using Podman

If you require that a Python image trusts both your custom Certificate Authorities (CAs) and the image’s built-in default CAs, use the Podman volume mount option to mount the custom certificate to the image. The application in your image can then use all these certificates.

Before you begin

  • The podman package is installed.
  • You have the CA certificate bundle in PEM format.

Procedure

  1. Store the hash of the certificate’s subject name in a temporary environment variable:
    $ CA_HASH=$(openssl x509 -noout -subject_hash -in <path_to_certificate>.pem)
  2. When you start the container, use a bind mount to pass the certificate to the container. For example:
    $ podman run \
        --rm \
        --volume <path_to_certificate>.pem:/etc/pki/tls/certs/${CA_HASH}.0:ro,Z \
        --env REQUESTS_CA_BUNDLE=/etc/pki/tls/certs/ \
        registry.access.redhat.com/hi/python

    This command uses the hash in the CA_HASH environment variable to define the destination of the bind mount. Additionally, it sets the REQUESTS_CA_BUNDLE environment variable in the image to the /etc/pki/tls/certs/ directory.

Add a custom CA bundle to Python images on OpenShift Container Platform

If you require that a Python image trusts both your custom Certificate Authorities (CAs) and the image’s built-in default CAs, use an OpenShift Container Platform ConfigMap to mount the custom certificate to the image. The application in your image can then use all these certificates.

Before you begin

  • You have access to OpenShift Container Platform CLI.
  • You have the CA certificate bundle in PEM format.
  • You have the permissions to create ConfigMaps and modify Pod specifications in the target namespace.

Procedure

  1. Display the hash of the certificate’s subject name:
    $ openssl x509 -noout -subject_hash -in <path_to_certificate>.pem
    12abc456

    You require the hash when you mount the ConfigMap into the Pod specification.

  2. Create a YAML configuration file that both defines the CA bundle and the volume mount necessary for your application to access it:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: custom-ca
    data:
      ca.crt: |
        -----BEGIN CERTIFICATE-----
        <certificate>
        -----END CERTIFICATE-----
        <more_certificates_if_needed>
    ---
    apiVersion: v1
    kind: Pod
    spec:
      containers:
      - name: app
        # Use registry.access.redhat.com/hi/python if you require only urllib
        # Use your custom image with the requests library installed for both libraries
        image: registry.access.redhat.com/hi/python
        env:
        - name: REQUESTS_CA_BUNDLE
          value: /etc/pki/tls/certs/
        volumeMounts:
        - name: custom-ca
          # Append .0 to the hash
          mountPath: /etc/pki/tls/certs/<hash>.0
          subPath: ca.crt
          readOnly: true
      volumes:
      - name: custom-ca
        configMap:
          name: custom-ca
  3. Apply the configuration:
    $ oc apply -f <configuration_file>.yaml