Persistent Storage

The Anjuna Nitro Runtime provides a seamless experience for running AWS Nitro Enclaves with persistent storage. This section describes the persistent storage options that the Anjuna Nitro Runtime supports and describes setting up an AWS Nitro Enclave with persistent storage.

Volume mounts & Bind mounts

The Anjuna Nitro Runtime provides two ways of storing persistent data: volume mounts and bind mounts. Both options look the same from within the enclave and provide a persistent mount point.

Volume mounts allow persisting data inside an enclave, and they are more performant than bind mounts. Volume mounts are created and managed by the Anjuna Nitro Runtime. Volume mounts are persistent, and the data is saved on the parent host. However, only an enclave can access the contents of the volume mount, and the parent host cannot mount that volume when it’s in use by an enclave. You can create multiple volume mounts with different sizes. A single enclave can mount a maximum of 1 volume at a time.

Bind mounts allow binding a file or a directory and its contents from the parent host into an enclave. It is less performant compared to volume mounts but does not require creating a dedicated volume.

Persistent Storage Security

Persistent volume mounts provide shared storage between the enclave and the untrusted VM host. This is a convenient way to externally configure an enclave application, provide input data, or obtain results from an enclave. However, if used incorrectly, this feature can open up vulnerabilities that could compromise the security of the enclave, either by exposing sensitive data or allowing an attacker to modify the operation of the enclave application. It is therefore important that the end user analyze the potential implications of opening access to an untrusted mount directory (the mountPath) and ensure that the enclave application does not trust any data within the file tree of a volume mount or access it in a way that could compromise security.

Some examples of potential security issues created by shared storage:

  • The enclave application reads configuration files from a volume mount, but allows for configuration options that are critical to the operation of the enclave and could be used to modify execution or obtain sensitive information.

  • The enclave application reads configuration files from a volume mount, does not allow critical options to be specified in the config, but due to a security bug (such as a buffer overflow in the config parser) allows an attacker to gain control of the enclave application.

  • The enclave application uses a volume mount for config files, but may also store sensitive data such as log files, which are exposed to the untrusted VM host.

  • The enclave application provides a way to customize functionality through external scripts or executables that are within a volume mount. These executables would be under the control of the host VM and could therefore be used to take control of the enclave application or modify its execution.

  • The enclave application accesses shared libraries on a volume mount, which allows an attacker to execute arbitrary code.

There are additional security implications of the forceMount option. This option provides a convenient way to mount over existing content in a docker image. This is useful when the docker image is distributed by a third party or is not easily changed. However, if used incorrectly it can expose the enclave application data or introduce additional vulnerabilities. The most secure option is to remove the conflicting resource from the docker image, when creating the EIF file. However, if this is not practical, then the forceMount option can be used to overwrite the target mountPath.

In order to limit the scope of the override, this option uses individual flags to specify what kinds of resources will be overwritten. These flags should be limited to the expected kind of conflicting resources. If, for example, a docker image has an empty directory for configuration files, which the user desires to configure externally from the host VM, the forceMount option could be set to empty, such as:

mounts:
- type: basic
  name: example-volume
  mountPath: /etc/app
  forceMount: empty

If instead of empty, the all option was used, an update to the docker image by the third party, with a new unexpected feature that has an executable script or shared library executed by the application now in the volume mountPath, would expose the application to an attack when a new EIF image is built. With the more restrictive option, a new built EIF image would fail to start, recognizing that there are now files where an empty directory was expected.

The full option can be used in cases where a directory contains content that the persistent storage should be mounted over. However, there are no checks in this case on what the content of the directory is and whether it might change in a critical way in the docker image. This flag should therefore be considered the least secure flag with the forceMount option.