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.