# Image Decryption Support
This document describes the method to configure image decryption support. Please note that this is still an experimental feature.

## Encrypted Container Images

Encrypted container images are OCI images that contain encrypted blobs. An example of how these encrypted images can be created through the use of [containers/skopeo](https://github.com/containers/skopeo/blob/master/docs/skopeo-copy.1.md). To decrypt these images,  `CRI-O` needs to have access to the corresponding private key(s).

## Key Models

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.

1. **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.

2. **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 [KEP](https://github.com/kubernetes/enhancements/pull/1066) that introduces `ImageDecryptSecrets`.


## Configuring Image Decryption for **Node** key model

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]
# decryption_keys_path is the path where the keys required for
# image decryption are located
decryption_keys_path = "/etc/crio/keys/"

```
`decryption_keys_path` 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 keys.

## Verification of the Decryption Capabilities

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,

```sh
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,

```sh
FATA[0010] pulling image failed: rpc error: code = Unknown desc = Error decrypting layer sha256:ecbef970c60906b9d4249b47273113ef008b91ce8046f6ae9d82761b9ffcc3c0: missing private key needed for decryption
```

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,
```sh
-----BEGIN RSA PRIVATE KEY-----

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,

```sh
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,

```sh
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`

```
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.
