---
name: Registry-registry_encrypt_images
title: Encrypting images for confidentiality in Container Registry
description: Protect the confidentiality of your Container Registry images by encrypting them with an RSA public-private key pair so that only trusted hosts can run them.
last-updated: 2026-08-11
---

> ## Documentation Index
> The table of contents for this documentation set is at https://cloud.ibm.com/docs/Registry?format=markdown
> The index for all IBM Cloud docs is at: https://cloud.ibm.com/docs/llms.txt
> Use these files to discover more information as needed.

# Encrypting images for confidentiality in Container Registry
{: #registry_encrypt}
{: toc-content-type="tutorial"}
{: toc-services="key-protect"}
{: toc-completion-time="2h"}

Protect the confidentiality of your Container Registry images by encrypting them with an RSA public-private key pair so that only trusted hosts can run them.
{: shortdesc}

Create an encrypted image so that people without the [private key](#x2034701){: term} can't access the content. Create the encrypted image by using an RSA public-private key pair to encrypt and decrypt the image. A public key is not a secret and anyone can use it to encrypt an image. A private key is a secret, and only users that have that private key can use it to decrypt the image.

Encryption is supported in IBM Cloud Container Registry and complies with the following standards:

- [`opencontainers/image-spec`](https://github.com/opencontainers/image-spec){: external}
- [`opencontainers/artifacts`](https://github.com/opencontainers/artifacts/pull/15){: external}

For more information about encrypting images, see [Encrypted container images for container image security at rest](https://developer.ibm.com/articles/encrypted-container-images-for-container-image-security-at-rest/){: external} and [Advancing image security and compliance through Container Image Encryption](https://www.youtube.com/watch?v=dYXhAxxPkqA){: external}.

## Before you begin
{: #registry_encrypt_prereqs}

- Complete the instructions in [Getting started with IBM Cloud Container Registry](https://cloud.ibm.com/docs/Registry?topic=Registry-getting-started&format=markdown#getting-started).
- Ensure that you have the most recent version of the `container-registry` command-line interface (CLI) plug-in for the IBM Cloud CLI, see [Updating the `container-registry` CLI plug-in](https://cloud.ibm.com/docs/Registry?topic=Registry-registry_setup_cli_namespace&format=markdown#registry_cli_update).
- Ensure that you have a private namespace to push your encrypted image to, see [Set up a namespace](https://cloud.ibm.com/docs/Registry?topic=Registry-getting-started&format=markdown#gs_registry_namespace_add).
- Install [Buildah version 1.15](https://buildah.io/releases/2020/06/27/Buildah-version-v1.15.0.html){: external} or later, so that you can build encrypted images. Buildah works in the Linux&reg; environment only. As an alternative to Linux&reg;, you can use a virtual machine or Docker image to run Buildah to build images.
- Install [Podman](https://podman.io/).

## Create the public-private key pair
{: #registry_encrypt_create}
{: step}

Create a public-private key pair by using OpenSSL commands.

1. Create a work directory, for example, `USER_KEYS`, in which to store the keys and change to that directory:

    ```txt
    mkdir USER_KEYS; cd USER_KEYS
    ```
    {: pre}

2. Use OpenSSL to create a private key, where `USER_KEY` is the name for your key's identity:

    ```txt
    openssl genrsa --out USER_KEYPrivate.pem
    ```
    {: pre}

3. Create a public key:

    ```txt
    openssl rsa -in USER_KEYPrivate.pem -pubout -out USER_KEYPub.pem
    ```
    {: pre}

    To use the private key in production, you must safely store and protect the private key in a suitable store. You might also want to manage the public key in the same way. For more information, see [Storing keys](#registry_encrypt_keys).
    {: requirement}

4. List the keys to ensure that they are created:

    ```txt
    ls -l
    ```
    {: pre}

5. To use this key pair to encrypt images, display the public key by running the following `cat` command:

    ```txt
    cat USER_KEYPub.pem
    ```
    {: pre}

    You get a response similar to the following output:

    ```txt
    -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv8Ny7dCWQ8Pdq1ddYSwk
    QOCB3lUEZVEyj9StX3jnISF/rxIsUZzJfbOrQN0fGkm+1sCCtltgQdztTjito8Fh
    DGflqQBSmV40XP3iZnNUJDrHuAol463Z/BuxxFXL3ry6rTosLGfrRwdQjxp8RSsn
    WyIIO2rmcqXZYe4SCtiMjMejLlTIDWLIMdYL3d6hA4DpgDLoh6EPmhKMVVwRt5b0
    ew5eMLcDuq6ButOM5yv4zYVHNrajY41NK+abSlFb6wzMg2AUDiC/MxV1LRq6mpyZ
    GJllx3LS1M1j7fDO3pmh/M0X7yD/4RgHwFaW4/4CQBw3fyxrOv0pZzZay+o
    -----END PUBLIC KEY-----
    ```
    {: screen}

## Encrypt the image
{: #registry_encrypt_image}
{: step}

Encrypt the image by using the public key and then build a container image by using a [Dockerfile](#x9860414){: term}.

1. Go to the directory where you store your apps, for example `MY_APP`.

    ```txt
    cd MY_APP
    ```
    {: pre}

2. Create the Dockerfile by running the following command:

    ```txt
    cat << EOF >> Dockerfile
    FROM nginx:latest
    RUN echo "some secret" > /secret-file
    EOF
    ```
    {: pre}

3. Use Buildah to create an unencrypted image by running the following command, where `NAMESPACE` is your namespace:

    ```txt
    buildah bud -t us.icr.io/NAMESPACE/MY_APP .
    ```
    {: pre}

    `us.icr.io/NAMESPACE/MY_APP` is committed to the local image store.

4. Encrypt the image by using the public key and upload the image to the registry by running the following commands and by specifying the JSON Web Encryption (`jwe`) protocol to encrypt the image, where `USER_KEYS/USER_KEYPub.pem` is the encryption key.

    ```txt
    buildah push --encryption-key jwe:..USER_KEYS/USER_KEYPub.pem us.icr.io/NAMESPACE/MY_APP
    ```
    {: pre}

    Buildah version 1.15 or later, uses Docker’s login credentials to authenticate. If these credentials don't work or you want to use an [API key](#x8051010){: term}, you can supply the `—-creds <username>` option, where `<username>` is the username. If you use the `—-creds <username>` the option, when requested, type in the password of the registry credential.
    {: tip}

    You get a response that informs you that the manifest is written to the image destination, which is the registry.

5. Check in your registry to make sure that the image is there.

## Pull and decrypt the image
{: #registry_encrypt_pull}
{: step}

Pull the image from the registry and decrypt it by using the private key.

1. To ensure that you are pulling from the registry and that you are not using the local cache, remove the image locally:

    ```txt
    buildah rmi -f us.icr.io/NAMESPACE/MY_APP
    ```
    {: pre}

2. (Optional) You can try to pull the image without providing the decryption key to confirm that the image can't be decrypted:

    ```txt
    buildah pull us.icr.io/NAMESPACE/MY_APP
    ```
    {: pre}

    The output contains a message similar to the following message:

    ```txt
    ...<truncated>...
    Error decrypting layer sha256:ab4ea03582e08a8e8fc35b778cc6f1a1fa797469fa9cc61cee85f703b316bb12: missing private key needed for decryption
    ERRO exit status 125
    ```
    {: screen}

3. Use Buildah to pull the image with the decryption key, where `USER_KEYS/USER_KEYPrivate.pem` is the decryption key and `us.icr.io/NAMESPACE/MY_APP` is the registry:

    ```txt
    buildah pull --decryption-key ../USER_KEYS/USER_KEYPrivate.pem us.icr.io/NAMESPACE/MY_APP
    ```
    {: pre}

    The encrypted image is retrieved from the registry, decrypted, and stored in the local image store.

4. Confirm that the image is stored by running Podman:

    ```txt
    podman run -it us.icr.io/NAMESPACE/MY_APP /bin/bash
    ```
    {: pre}

## Storing keys
{: #registry_encrypt_keys}

To use the private key in production, you must safely store and protect the private key. You might also want to manage the public key in the same way to control who can build images. You can use [IBM Key Protect](https://cloud.ibm.com/docs/key-protect?topic=key-protect-about&format=markdown) to store and protect your keys.

IBM Key Protect stores symmetric keys rather than the asymmetric PKI keys that are used for image encryption. You can add your keys separately as two IBM Key Protect standard keys by using the dashboard, CLI, or API. IBM Key Protect requires that only Base64 data is imported. To obtain pure Base64 data, you can encode the PEM files by running `"openssl enc -base64 -A -in USER_KEYPrivate.pem -out USER_KEYPrivate.b64"` before you load the Base64 content, and reverse this action to obtain the usable key again by running `"openssl enc -base64 -A -d -in USER_KEYPrivate..b64 -out USER_KEYPrivate.pem"`.

For more information about how to use IBM Key Protect to store and protect your keys, see [Bringing your encryption keys to the cloud](https://cloud.ibm.com/docs/key-protect?topic=key-protect-importing-keys&format=markdown) and [Importing your own keys](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial&format=markdown#import-keys).

As an alternative, you can protect your keys in your own store by using an IBM Key Protect root key to wrap them. This action means that you must unwrap them again by using IBM Key Protect and the valid root key.

For example, to wrap keys by using the CLI, run the command `"ibmcloud kp key wrap ROOT_KEY_ID -p <base64 encoded image key>"` and to unwrap keys, run the command `"ibmcloud kp key unwrap ROOT_KEY_ID -p <base64 cyphertext>`, where `ROOT_KEY_ID` is the ID of the root key that you are using.

For more information about how you can protect your keys in your own store by using an IBM Key Protect root key to wrap them, see [Wrapping keys](https://cloud.ibm.com/docs/key-protect?topic=key-protect-wrap-keys&format=markdown).

Encrypted images are not scanned by Vulnerability Advisor.
{: note}

## Next steps
{: #registry_encrypt_next}

Run your encrypted image in a Red Hat&reg; OpenShift&reg; on IBM Cloud&reg; cluster by using the [Image Key Synchronizer cluster add-on](https://cloud.ibm.com/docs/openshift?topic=openshift-images&format=markdown#encrypted-images).