Anjuna Nitro Enclave configuration

The Anjuna Nitro Enclave Configuration file contains information that the Anjuna Nitro Runtime needs in order to set up the application’s environment and start the application in an AWS Nitro Enclave.

Specify the Anjuna Nitro Enclave Configuration file (config.yaml in the following example) when building the Enclave Image File (EIF) by using the anjuna-nitro-cli build-enclave command:

anjuna-nitro-cli build-enclave --docker-uri nginx:latest --output-file nginx.eif --enclave-config-file config.yaml

The Anjuna Nitro Enclave Configuration file allows you to configure the application running in the enclave, without changing the Docker image used to create the EIF. The file can handle the following tasks:

  • Setting up new environment variables (or overriding existing ones).

  • Adding files to the application’s file system.

  • Setting the hostname of the enclave.

  • Selecting ports to expose.

  • Changing the command that starts the application in the enclave.

  • Specifying the S3 bucket that contains encrypted secrets for the application running in the enclave.

  • Specifying the allow list of environment variables and files that are permitted to be provided via encrypted secrets.

Configuration files should be less than 560 MB in size in order to successfully build the enclave.

Encrypted configuration file

The Anjuna Nitro Enclave Configuration file is inserted into the EIF in the same area as the application, so it affects the PCR0 and PCR2 measurements.

Yet this configuration file is not encrypted, and you should not insert sensitive data (secrets) in this file.

To securely provide secrets to your application, use the anjuna-nitro-encrypt tool to encrypt a configuration file with an AWS KMS key. Then upload this new encrypted configuration file to an S3 bucket, or save it to a local file.

The Anjuna Nitro Runtime will pull, decrypt, and apply the encrypted secrets at enclave boot time. (This will happen as long as the AWS Nitro Enclave is allowed to decrypt data using the AWS KMS key. I.e., the attestation quote coming from the enclave matches the policy in AWS KMS.)

Because the encrypted configuration is pulled and applied at enclave boot time, if you update the encrypted configuration file, you must restart the enclave to see the updated values.

Encrypted configurations are specified using an encryptedConfig entry in the enclave configuration:

encryptedConfig:
  type: <s3/local>
  [type specific fields]
  allowList:
    environment:
      [list of allowed environment variables]
    files:
      [list of allowed files]

Option 1 - Encrypted secrets stored in AWS S3

If the encrypted configuration file is stored in AWS S3, you must add the location of the S3 object to the Anjuna Nitro Enclave Configuration file. To specify the location of the S3 object (where your encrypted configuration file resides), set type: s3 and uri: s3://<path to your encrypted S3 object> under encryptedConfig. For example:

encryptedConfig:
  type: s3
  uri:  s3://my-bucket.nitro.my-application/kms-encrypted-data.bin
  allowList:
    ...

Option 2 - Encrypted secrets stored in a local file

If the encrypted configuration file is stored in a local file, you must specify its path when starting the enclave through the anjuna-nitro-cli run-enclave command. To specify that the encrypted configuration is local, set type: local under encryptedConfig. For example:

encryptedConfig:
  type: local
  allowList:
    ...

Allow list

An "allow list" is required when using encrypted configuration files. The allow list lists the names of files and environment variables that are allowed to be provided via encrypted configuration files, regardless of where they are stored.

Extra items are not allowed: if the encrypted configuration file contains environment variables or files that are not included in the allow list, the enclave will not launch.

The encrypted configuration is not required to supply values for everything in the allow list. If the allow list contains files or environment variables not specified in the encrypted configuration file, they will be ignored, or a default value from the enclave configuration file will be used if present.

Setting an Allow List is mandatory.

Encrypted configuration files have the same format as the Anjuna Nitro Enclave Configuration file, but are restricted to only the version, environment, and files keys. Entries defined in encrypted configuration files override entries defined in the enclave configuration file.

To specify an allow list for files and environment variables that are permitted to be specified in your encrypted configuration file, use the encryptedConfig.allowList key, as in the following example:

encryptedConfig:
  type: ...
  ...
  allowList:
    environment:
      - ENV_VAR_A
      - ENV_VAR_B
    files:
      - FILE_A
      - FILE_B

Specifying any keys other than environment or files in the allowList block is invalid. You do not have to specify both keys. Each key may only be specified once.

Anjuna Nitro Enclave configuration entries

The Anjuna Nitro Enclave Configuration should be a valid YAML file.

Version

The Anjuna Nitro Enclave Configuration must contain a version entry:

version: 1.8

The Anjuna Nitro Runtime v1.47.0001 supports AWS Nitro Enclave Configuration v1.8 and below.

Environment variables

The environment entry contains an array of strings, where each string represents an environment variable and its value. The string should have the following format:

name=value

For example:

environment:
  - NGINX_HOST=foobar.com
  - NGINX_PORT=80

The variables defined in this section override the ones that were defined in the Docker container.

The value for an environment variable must be a literal (i.e. references to other environment variables are not supported).

Add environment variables to the Encrypted configuration file to safely provide these values, since the Anjuna Nitro Enclave Configuration file is not encrypted.

If the same environment variable is defined in more than one place, the following describes the precedence used:

  1. The environment of the encryptedConfig takes highest precedence, overwriting any other definition of that same environment variable.

  2. Then, the environment variables defined in the parent instance or in the K8s Pod manifest are second in precedence. They are only applied if the environment variable is explicitly set as allowed in the envVars.allow field of the untrustedConfig key in the enclave configuration file.

  3. Then, the values defined in the environment section of the enclave config file that is provided when building the enclave are considered.

  4. Finally, the environment variables defined in the original Docker container image have the lowest precedence.

Configuration files

The files entry contains an array of files with the following attributes:

  • path (required): The path where the file will be created. The Anjuna Nitro Runtime will create the intermediate directories if they do not exist.

  • mode (optional): The permissions on the file (in octal notation). The default value is 0644 (which maps to [-rw-r—​r--] in symbolic notation).

  • owner (optional): The owner (user) of the file. The default value is root.

  • group (optional): The owner (group) of the file. The default value is the user owner.

  • content (optional): The content of the file (if not provided, an empty file will be created).

  • directory (optional): When set to true, path specifies a directory to create instead of a file.

files:
  - path: "/my-application/etc/config.toml"
    mode: 0644
    owner: root
    group: root
    content: |-
      [database]
      server = "192.168.1.1"
      ports = [ 8000, 8001, 8002 ]
      connection_max = 5000
      enabled = true

This example defines the file /my-application/etc/config.toml with the following content:

[database]
server = "192.168.1.1"
ports = [ 8000, 8001, 8002 ]
connection_max = 5000
enabled = true
Add configuration file attributes to the Encrypted configuration file to safely provide these values, since the Anjuna Nitro Enclave Configuration file is not encrypted.
You can also create an enclave configuration file with binary data. See Including binary data in an enclave configuration file in the How-to guides section for more details.

Exposed ports

Use the exposedPorts: entry to specify one or more ports to expose from the AWS Nitro Enclave.

If the exposedPorts: entry is not added, then all ports will be exposed.

When using the exposedPorts: entry without specifying any ports, then all ports will be exposed.

Example for exposing ports 443 and 80:

exposedPorts:
  - 443
  - 80

Docker overrides

The Anjuna Nitro Enclave Configuration can be used to override Dockerfile entries at runtime, without modifying the Dockerfile itself.

Entrypoint

The Anjuna Nitro Runtime executes the command specified by the ENTRYPOINT and CMD entries from the original Dockerfile. If you want to override this value, you can specify the entrypoint and its command-line arguments.

entrypoint: [program, 1st_arg, 2nd_arg, ...]

Note that the syntax above can alternatively be written like this for the same result:

entrypoint:
  - program
  - 1st_arg
  - 2nd_arg
  - ...

Command

The Anjuna Nitro Runtime executes the command specified by the ENTRYPOINT and CMD entries from the original Dockerfile. If you want to override this value, you can specify the CMD command and its command-line arguments.

command: [program, 1st_arg, 2nd_arg, ...]

Note that the syntax above can alternatively be written like this for the same result:

command:
  - program
  - 1st_arg
  - 2nd_arg
  - ...

User and group

The Anjuna Nitro Runtime executes the Container Command with the system user and group specified by the USER entry from the original Dockerfile. If you want to override this value, you can specify the new user and optionally, group.

The format of this string is a valid username or a decimal user ID (UID). This can be followed by an optional valid group name or a decimal group ID (GID) separated by a colon :.

User and group IDs do not necessarily need to exist in /etc/passwd or /etc/group. If the group is not specified, it defaults to the user’s default group. If that cannot be determined then the root (UID=0) group is used.

username: user_name_or_id[:group_name_or_id]

Working directory

The Anjuna Nitro Runtime executes the Container Command with the working directory specified by the WORKDIR entry from the original Dockerfile. If you want to override this value, you can specify the new working directory.

The working directory must be an absolute path.

workdir: /path/to/workdir

Environment variables

Hostname

You can change the default hostname of the enclave to any value with the hostname field.

hostname: anjuna-enclave

The value of hostname is inserted automatically in the file /etc/hosts on the file system of the application running in the AWS Nitro Enclave.

Persistent storage mounts

The mounts entry contains an array of mounts with the following attributes:

  • type (required): The type of the mount; should be basic or block

  • name (required): The name of the volume mount

  • mountPath (required): The path to mount the volume to inside the enclave

  • forceMount (optional): NOTE: Read Persistent storage security on the potential security implications of persistent storage and this option. The default behavior is to abort enclave startup if a conflicting resource is found at the volume mountPath. This option consists of a string of flag values separated by commas. Multiple flags can be specified, each flag enabling overwriting of different types of conflicting resources and that can be selected from the following list:

    • file: Enable overwriting existing file at mountPath

    • empty: Enable overwriting existing empty directory at mountPath

    • full: Enable overwriting existing directory with content at mountPath

    • all: Enables all of the above flags

mounts:
  - type: basic
    name: example-volume
    mountPath: /shared/example-volume

Untrusted configuration

The Anjuna Enclave Configuration provides the user a configuration that is trusted, either through the configuration file attached at enclave-build-time or through an encrypted configuration file. However, there are cases where you need to provide data to the software running in an enclave that is not known in advance and does not need to be trusted. One example is the IP address of a logging server. The Anjuna Nitro Runtime provides a way to set this type of untrusted configuration.

An Enclave can fetch values for environment variables that do not affect the Enclave’s measurements and do not need to be attested. The configuration entry untrustedConfig and its sub-entries, envVars and allow, contain an array of environment variables to pull from the parent EC2 instance or from a Kubernetes ConfigMap.

For detailed information about fetching information from a non-attested and non-measured configuration, refer to the Untrusted configuration section.
The environment variable ANJ_ENCLAVE_KMS_DECRYPT_RETRY_TIMEOUT_SECONDS is allowed as untrusted by default.
untrustedConfig:
  envVars:
    allow:
      - LOG_SERVER_ADDRESS
      - LOG_LEVEL

This example configuration allows the Enclave to fetch the environment variables LOG_SERVER_ADDRESS and LOG_LEVEL from the parent EC2 instance.

Example

Here is a complete example of an Anjuna Nitro Enclave Configuration:

version: 1.8

environment:
  - MY_APP_HOST=anjuna-enclave
  - MY_APP_CONFIG=/my-application/etc/config.toml

encryptedConfig:
  type: s3
  uri: s3://my-bucket.nitro.my-application/kms-encrypted-data.bin
  allowList:
    environment:
      - MY_APP_SECRET
    files:
      - MY_ENCRYPTED_CONFIG_FILE

hostname: anjuna-enclave

command: [nginx-debug, '-g', 'daemon off;']

files:
  - path: "/my-application/etc/config.toml"
    mode: 0644
    owner: root
    group: root
    content: |
      [database]
      server = "192.168.1.1"
      ports = [ 8000, 8001, 8002 ]
      connection_max = 5000
      enabled = true

exposedPorts:
  - 8000
  - 8001
  - 8002

mounts:
  - name: app-data
    type: basic
    mountPath: /shared/app-data