Project: CRI-O (Runtime / Container Runtime)
File: decryption.md

This document describes the method to configure image decryption support. Please note that this is still an experimental feature. Encrypted container images are OCI images that contain encrypted blobs. An example of how these encrypted images can be created through the use of . To decrypt these images, `CRI-O` needs to have access to the corresponding private key(s). Encryption ties trust to an entity based on the model in which a key is associated with it. We call this the key model. There are two currently supported key models in which encrypted containers can be used. These are based on two main use cases. Node Key Model - In this model encryption is tied to workers. The use case here revolves around the idea that an image should be only decryptable on the trusted host. Although the granularity of access is more relaxed (per node), it is beneficial because of the various node based technologies that help bootstrap trust in worker nodes and perform secure key distribution (i.e. TPM, host attestation, secure/measured boot). In this scenario, runtimes are capable of fetching the necessary decryption keys. Multitenant Key Model - This model is not yet supported by CRI-O, but will be in the future. In this model,the trust of encryption is tied to the cluster or users within a cluster. This allows multi-tenancy of users and is useful in the case where multiple users of Kubernetes each want to bring their encrypted images. This is based on the that introduces `ImageDecryptSecrets`. In order to set up image decryption support, add an overwrite to `/etc/crio/crio.conf.d/01-decrypt.conf` as follows: ```toml [crio.runtime] decryptionkeyspath = "/etc/crio/keys/" ``` `decryptionkeyspath` should be the path where `CRI-O` can find the keys required for image decryption. After modifying this config, you need to restart the `CRI-O` service. Alternatively, if you are starting the `CRI-O` from the command line, the argument `--decryption-keys-path` can be provided pointing to the folder that contains required decryption

Although the latest master branch of the `docker/distribution` registry supports encrypted images, many popular public registries such as Docker hub or `quay.io` don't support encrypted images yet. For the easy verification of the image decryption capabilities, we are hosting a test image at, `docker.io/enccont/encrypted_image:encrypted` Go ahead and try to download this image using the read-only credentials given below, ```shell crictl -r unix:///var/run/crio/crio.sock pull docker.io/enccont/encrypted_image:encrypted ``` Since we haven't provided `CRI-O` the access to the private key required to decrypt this image you should see a failure like this on your console, <!-- markdownlint-disable MD013 --> ```text FATA[0010] pulling image failed: rpc error: code = Unknown desc = Error decrypting layer sha256:ecbef970c60906b9d4249b47273113ef008b91ce8046f6ae9d82761b9ffcc3c0: missing private key needed for decryption ``` <!-- markdownlint-enable MD013 --> This is intended behavior and proof that indeed the encrypted images cannot be used without having access to the correct private key. The image can be decrypted using following key, ```text --BEGIN RSA PRIVATE KEY-- MIICXAIBAAKBgQDoJBuK1hQ5aCbF93uE6jzRm8v5icUNFL5j+DO9hnM5j/8XFTzp 40N2M2/ObLf2qwmWSivwj5LJR/+5ceS8jqVBAcJpckwOXupu3A5o4KgJo15s6v57 4+0wfraNJ/OapqBc7lGFBsj+XwdmegwYYqy41DnYNSzYS4Mov+v7RI014wIDAQAB AoGALCuiqfouAvZUWlrKv/Gp/OA+IY8bVW/bAj6Z6bgJeKxzhzrdSkuZ7IXBAnAh WOgWfOhEEBPhhDcU635GXbJusuD/bLBJPOTxiwCFazffm8zVGSQCndfTVxgCM4hn +5bH6o/cSGQ4E6SLJQeEr8y/J0bMlNMkOco9F1FL1ZgwXGECQQD9/mDwWLJjbdEa jmGtoPspGz80XDb1jRI09jKDXB826/cBUD+X/P50aTkU+XSJXVfa5F6zhzf/O7C8 07bVnn2pAkEA6fmJ+Jx/Cupy7jRHzIdKAN/7T9QJBIXVDZLz5ulFWLjYkNotpkxk f0ZSIOvlD7vv5lOifRFivd680XjxIATWqwJARJ35QFUl9DiRuhPnDYok8Cj9PT8A VfwDhC1S3iv//s1mkINGeuANOhPHKQRvWEDQYEE72FJabWiJyamEhldn6QJAFjLw 3j+q5hQ8d1FKhqNHaDHYHEjX2jAAeNs6fOwhAjv3gDbTIfYZiuHXJPx8rTN9nXLN 9ePSZIVfkNhSuGD9JQJBAI+mobcxj7WkdLHuATdAso+N89Yt7xHoG49c8gz81ufP vvLPtYytL4ftpiVO3fTfPP90ze8qYPiNaFqMHYDkQ+M= --END RSA PRIVATE KEY-- ``` Please save this key in the folder `/etc/crio/keys` with the name of your choice. Now that we have the private key that can be used by `CRI-O`, let's try to download the image again, ```shell crictl -r unix:///var/run/crio/crio.sock pull docker.io/enccont/encrypted_image:encrypted ``` If `CRI-O` was able to read the keys, it would have decrypted the image. You should see something like this on your console, ```text Image is up to date for docker.io/enccont/encrypted_image@sha256:2c3c078642b13e34069e55adfd8b93186950860383e49bdeab4858b4a4bdb1bd ``` Verify that image indeed got downloaded and decrypted using `crictl -r unix:///var/run/crio/crio.sock images` ```text IMAGE TAG IMAGE ID SIZE docker.io/enccont/encrypted_image encrypted 5eb6083c55f01 130MB ``` Please note that the confidentiality provided by the encrypted images could get compromised if the private keys are accessed by unauthorized and/or unintended entities. Also, in case of loss of private key, there is no way to access the contents of the encrypted image rendering it completely unusable. Hence, it's extremely important to keep the private keys securely and safely.