Adding Custom CA to Ubuntu Core

I have a requirement to allow customers to provide site-specific Certificate Authorities (CAs) for environments that use transparent TLS inspection, which is a very common deployment scenario. While reviewing the available Ubuntu Core options, I found two system options that appear to address custom CA management.

The first is store-certs, which is specifically used by snapd for Snap Store communication. I have tested this mechanism and understand its purpose. Adding a CA or CA bundle through store-certs allows snapd operations such as snap refresh and snap install to successfully traverse TLS inspection without requiring firewall exceptions.

The second option is pki.certs.custom, which appears to provide a certificate repository managed by snapd. When a certificate bundle is imported, it materialized under /var/lib/snapd/pki/v1.

For example, importing a bundle named cabundle creates:

/var/lib/snapd/pki/v1/cabundle.crt

I also observed that custom certificates are merged into:

/var/lib/snapd/pki/v1/merged/ca-certificates.crt

The resulting trust bundle appears functional (with transparent TLS inspection). For example, OpenSSL validation succeeds when I explicitly reference the generated bundle:

openssl s_client \
  -connect google.com:443 \
  -CAfile /var/lib/snapd/pki/v1/merged/ca-certificates.crt \
  -verify_return_error

Result:

Verification: OK

What is unclear to me is how the pki.certs.custom trust store is intended to be consumed. While certificates are successfully imported and merged, I have not found evidence that the resulting trust bundle is automatically used by the operating system, OpenSSL, or confined snaps.

My questions are:

  • What components are expected to consume certificates installed through pki.certs.custom?

  • Are there downstream actions or integrations that occur after the certificate is accepted and written under /var/lib/snapd/pki/v1?

  • Is the expectation that individual snaps discover and reference the generated trust bundle themselves?

  • Is there a supported mechanism for exposing these certificates to applications in a consistent, system-wide manner?

  • Are there future plans for broader trust store integration on Ubuntu Core?

Our Ubuntu Core devices host several independent internet-connected snaps, including device management, observability, and cloud-connected product applications. Each of these may need to operate in customer environments that perform TLS inspection.

Before designing and implementing our own certificate distribution and trust model, I would like to understand whether a supported platform-level solution already exists. Ideally, I would like to:

  1. Accept customer-provided CA bundles.

  2. Install them in a central, supported location.

  3. Provide a documented and consistent mechanism for snap developers to discover and consume those certificates.

  4. Avoid creating custom implementations if Ubuntu Core already provides a recommended approach.

Any guidance on the intended use of pki.certs.custom and the recommended strategy for custom CA management on Ubuntu Core would be greatly appreciated.

In the absence of a first-class interface that allows confined snaps to discover and consume certificates installed through pki.certs.custom, I investigated whether a trusted certificate-provider snap could bridge the gap using existing system-files and content interfaces.

The approach would use a trusted snap with read-only system-files access to:

/var/lib/snapd/pki/v1/

The snap would consume:

/var/lib/snapd/pki/v1/merged/ca-certificates.crt

and republish the merged trust bundle through a content interface for other confined snaps to consume.

The provider snap would:

  1. Read the snapd-managed merged CA bundle.
  2. Synchronize it into its own $SNAP_DATA.
  3. Expose the bundle through a content interface.
  4. Allow consuming snaps to perform any runtime-specific trust store integration required by OpenSSL, Java, Electron, or other frameworks.

This appears to provide a centralized trust model for multiple confined snaps while avoiding each snap/application having to independently manage customer-provided CA certificates.

Before moving forward with this approach, I have more questions:

  1. Is reading /var/lib/snapd/pki/v1/merged/ca-certificates.crt considered a supported use case?
  2. Is the structure of /var/lib/snapd/pki/v1 considered stable, or is it an implementation detail that could change?
  3. Is using system-files access and a content-provider snap the recommended pattern today?
  4. If not, how are snap applications expected to consume certificates installed via pki.certs.custom?
  5. Is there a longer-term roadmap for exposing these certificates to confined applications through a supported platform interface?

For reference, the implementation appears relatively straightforward and is included below to illustrate the proposed architecture rather than as a recommended solution.

Provider snapcraft.yaml updates:

plugs:
  merged-ca-certs:
    interface: system-files
    read:
      - /var/lib/snapd/pki/v1

# Republished to limit system-file access
# and the impact of future snapd changes
slots:
  ca-certificates:
    interface: content
    content: bd-merged-ca-certs-v1
    source:
      read:
        - $SNAP_DATA/certs
apps:
  my-app:
    daemon: simple
    command: bin/wrapper.sh
    restart-delay: 2s
    restart-condition: always
    plugs:
      - network
      - merged-ca-certs

Provider wrapper.sh updates

MERGED_CA_BUNDLE="/var/lib/snapd/pki/v1/merged/ca-certificates.crt"
SHARED_CA_DIR="${SNAP_DATA}/certs"
if [ -s "${MERGED_CA_BUNDLE}" ]; then
  mkdir -p "${SHARED_CA_DIR}" # << Add/Move to install hook
  cp "${MERGED_CA_BUNDLE}" "${SHARED_CA_DIR}/ca-certificates.crt"
  export SSL_CERT_FILE="${SHARED_CA_DIR}/ca-certificates.crt"
  export SSL_CERT_DIR="${SHARED_CA_DIR}"
  # Add runtime-specific trust store updates (Java, Electron, etc.)
fi

Consumer snapcraft.yaml updates

plugs:
  ca-certificates:
    interface: content
    content: bd-ca-certificates-v1
    target: $SNAP_DATA/ca-certificates

Consumer wrapper.sh updates

SHARED_CA_BUNDLE="${SNAP_DATA}/ca-certificates/ca-certificates.crt"
if [ -s "${SHARED_CA_BUNDLE}" ]; then
  export SSL_CERT_FILE="${SHARED_CA_BUNDLE}"
  export SSL_CERT_DIR="$(dirname "${SHARED_CA_BUNDLE}")"
  # Add runtime-specific trust store updates (Java, Electron, etc.)
fi
1 Like

This pull request appears to address our needs by bind-mounting /var/lib/snapd/pki/v1/merged to /etc/ssl/certs within the snap mount namespace on Ubuntu Core.