

# Attestable AMIs
<a name="attestable-ami"></a>

An Attestable AMI is an Amazon Machine Image (AMI) with a corresponding cryptographic hash that represents all of its contents. The hash is generated during the AMI creation process, and it is calculated based on the entire contents of that AMI, including the applications, code, and boot process.

## Maintaining an Attestable State
<a name="maintain-attestability"></a>

An instance's measurements are based on its initial boot state. Any software or code changes made to the instance after launch and that persist after restarts will change the instance's measurement after restarts. If the measurements are altered, they deviate from the reference measurements of the Attestable AMI, and the instance will no longer be able to successfully attest to AWS KMS after the instance restarts. Therefore, for Attestable AMIs to be useful, instances need to return to their original boot state after they restart.

Always returning to the original boot state ensures that an instance can successfully attest after it restarts. The following utilities can be used to ensure that your instances remain attestable after restarts:
+ `erofs` — Enhanced Read-Only File System. This utility ensures that your root filesystem is read-only. With this utility, writes to the filesystem, including `/etc`, `/run`, and `/var`, are stored in memory and lost when the instance is restarted, leaving the root filesystem in its original launch state. For more information, see the [erofs documentation](https://docs.kernel.org/filesystems/erofs.html).
+ `dm-verity` — Provides integrity protection for the read-only root filesystem. The utility calculates a hash of the filesystem blocks and stores it in the kernel command line. This allows the kernel to verify the integrity of the filesystem during boot. For more information, see the [ dm-verity documentation](https://docs.kernel.org/admin-guide/device-mapper/verity.html).

## Requirements for creating Attestable AMIs
<a name="ami-attestable-requirements"></a>

Attestable AMIs have the following requirements:
+ **Base operating system** – Amazon Linux 2023 and [NixOS](https://github.com/aws/nitrotpm-attestation-samples)
+ **Architecture** – `x86_64` or `arm64` architecture
+ **TPM support** – NitroTPM must be enabled. For more information, see [Requirements for using NitroTPM with Amazon EC2 instances](enable-nitrotpm-prerequisites.md).
+ **Boot mode** – UEFI boot mode must be enabled.

**Topics**
+ [Maintaining an Attestable State](#maintain-attestability)
+ [Requirements for creating Attestable AMIs](#ami-attestable-requirements)
+ [Creating Attestable AMIs](#sample-ami)
+ [Build the sample image description](build-sample-ami.md)
+ [Sample Amazon Linux 2023 image description](al2023-isolated-compute-recipe.md)
+ [Customize the sample image description](customize-sample-ami.md)
+ [Compute PCR measurements](create-pcr-compute.md)

## Creating Attestable AMIs
<a name="sample-ami"></a>

To create an Attestable AMI, you will need to use Amazon Linux 2023 with [KIWI Next Generation (KIWI NG)](https://osinside.github.io/kiwi/). Amazon Linux 2023 provides all of the software and utilities needed to build an Attestable AMI using KIWI NG. 

KIWI NG is an open-source tool for building pre-configured Linux-based images. KIWI NG uses XML *image descriptions* that define the contents of an image. The image description specifies the base operating system, software, kernel configuration, and scripts to run in order to build a ready-to-use AMI for a specific use case.

During AMI build time, you need to use the `nitro-tpm-pcr-compute` utility to generate the reference measurements based on the Unified Kernel Image (UKI) generated by KIWI NG. For more information about using the `nitro-tpm-pcr-compute` utility, see [Compute PCR measurements for a custom AMI](create-pcr-compute.md).

AWS provides a sample Amazon Linux 2023 image description that includes all configurations needed to configure an EC2 instance in an isolated compute environment. For more information, see [Build the sample Amazon Linux 2023 image description](build-sample-ami.md).

# Build the sample Amazon Linux 2023 image description
<a name="build-sample-ami"></a>

AWS provides a sample Amazon Linux 2023 image description that you can use as a starting point for creating your own custom Attestable AMIs for your workloads. The sample image description includes Amazon Linux 2023 as the base operating system, `dm-verity` and `erofs` configurations for filesystem immutability, and it removes all interactive access (such as SSH, EC2 instance connect, and serial console) to create an isolated compute environment. For more information about the sample image description, see the [ Github repo](https://github.com/amazonlinux/kiwi-image-descriptions-examples).

The sample image description automatically installs the NitroTPM tools (`nitro-tpm-pcr-compute` and `nitro-tpm-attest`) in the built image in the `/usr/bin/` directory. This ensures that the tools are preinstalled on instances launched from the AMI.

The sample image description includes a script, `edit_boot_install.sh`, which includes the commands needed to generate the reference measurements. The script mounts the raw disk image file (`.raw`) created by KIWI NG to a loopback device, locates the UKI, which has the `.efi` file extension, and then runs the `nitro-tpm-pcr-compute` utility to generate the reference measurements for the AMI. The script is automatically executed by KIWI NG during build time.

This tutorial shows you how to build the sample image description to create an Attestable AMI.

For more information about creating your own image descriptions, see the following KIWI NG documentation:
+ [Quick Start](https://osinside.github.io/kiwi/quickstart.html)
+ [Image Description](https://osinside.github.io/kiwi/image_description.html)
+ [Sample Amazon Linux 2023 image description](https://github.com/amazonlinux/kiwi-image-descriptions-examples)

Prerequisites

Your IAM identity must have the following permissions to complete this tutorial:
+ `ebs:CompleteSnapshot`, `ebs:StartSnapshot`, and `ebs:PutSnapshotBlock` on `arn:aws:ec2:*::snapshot/*`
+ `ec2:RegisterImage` on all resources

**To build the sample Amazon Linux 2023 image description using KIWI NG**

1. Launch an Amazon EC2 instance using the latest AL2023 AMI. To ensure that your instance has enough storage space to build the AMI, ensure that you provision at least 12 GB of storage.

1. Install the required dependencies. The following command installs the following utilities:
   + `kiwi-cli`
   + `veritysetup`
   + `erofs-utils`
   + `aws-nitro-tpm-tools`

   ```
   sudo dnf install -y kiwi-cli python3-kiwi kiwi-systemdeps-core python3-poetry-core qemu-img veritysetup erofs-utils git cargo aws-nitro-tpm-tools
   ```

1. Install the `coldsnap` utility. This utility enables you to create Amazon EBS snapshots from raw image data. You'll use this utility to create an EBS snapshot from the raw disk image file created by KIWI NG.

   ```
   git clone https://github.com/awslabs/coldsnap.git
   cd coldsnap
   cargo install --locked coldsnap
   cd ..
   ```

1. Get the sample image description files.

   ```
   sudo dnf install kiwi-image-descriptions-examples
   ```

   The sample image description files are downloaded to the following directory: `/usr/share/kiwi-image-descriptions-examples/al2023/attestable-image-example`

1. Build the sample image description using the KIWI NG `system build` command. The following command creates a raw disk image file in the `./image` directory.

   ```
   sudo kiwi-ng \
   --color-output \
   --loglevel 0 \
   system build \
   --description /usr/share/kiwi-image-descriptions-examples/al2023/attestable-image-example \
   --target-dir ./image
   ```

   For more information, see the [ kiwi-ng system build](https://osinside.github.io/kiwi/commands/system_build.html) documentation.

1. Get the reference measurements for the AMI. The measurements are generated by the `nitro-tpm-pcr-compute` utility during image build time in the previous step. You can locate the reference measurements in the following file: `./image/pcr_measurements.json`.

   The measurements are provided in the following JSON format:

   ```
   {
     "Measurements": {
       "HashAlgorithm": "SHA384 { ... }",
       "PCR4": "PCR4_measurement",
       "PCR7": "PCR7_measurement",
       "PCR12": "PCR12_measurement"
     }
   }
   ```

1. Use the `coldsnap` utility to upload the raw disk image created by KIWI NG to an EBS snapshot. The command returns the snapshot ID. Make a note of the ID, you'll need it for the next step.

   ```
   SNAPSHOT=$(.cargo/bin/coldsnap upload ./image/al2023*.raw)
   echo "Created snapshot: $SNAPSHOT"
   ```

   For more information about the `coldsnap` utility, see the [ coldsnap GitHub repo](https://github.com/awslabs/coldsnap).

1. Register a TPM 2.0-enabled AMI with UEFI boot mode using the snapshot from the previous step. For `--architecture`, specify `x86_64` for Intel, or `arm64` for Graviton.

   ```
   aws ec2 register-image \
   --name "attestable_isolated_al2023_ami" \
   --virtualization-type hvm \
   --boot-mode uefi \
   --architecture x86_64|arm64 \
   --root-device-name /dev/xvda \
   --block-device-mappings DeviceName=/dev/xvda,Ebs={SnapshotId=${SNAPSHOT}} \
   --tpm-support v2.0 \
   --ena-support
   ```

# Sample Amazon Linux 2023 image description
<a name="al2023-isolated-compute-recipe"></a>

The sample Amazon Linux 2023 image description has the following characteristics: 

1. **Unified Kernel Image (UKI) boot** — Boot using a single, signed binary that combines the kernel, `initrd`, and boot parameters into one immutable image.

1. **Read-only root filesystem** — Use Enhanced Read-Only File System (`erofs`) with dm-verity protection to ensure that the root filesystem cannot be modified and maintains cryptographic integrity verification.

1. **Ephemeral overlay filesystem** — Create a temporary overlay filesystem that allows temporary writes to directories like `/etc`, `/run`, and `/var`. Since this overlay filesystem exists only in memory, all changes are automatically lost when the instance reboots, ensuring the system returns to its original trusted state.

1. **Disabled remote access methods** — Remove the following remote access mechanisms to prevent remote access:    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/al2023-isolated-compute-recipe.html)

   \$1 For more information, see [ Image Description Elements](https://osinside.github.io/kiwi/image_description/elements.html#packages-ignore).

# Customize the sample Amazon Linux 2023 image description for your workload
<a name="customize-sample-ami"></a>

You can customize the sample Amazon Linux 2023 image description and include the software packages, scripts, and files that are needed for your specific workload. Customizations are achieved by adding to or modifying various elements in the KIWI NG image description.

**Topics**
+ [Repository management](#prepare-custom-image-repos)
+ [Package management](#customize-sample-ami-packages)
+ [Adding files and directories](#customize-sample-ami-overlay)
+ [Adding custom scripts](#customize-sample-ami-script)

## Repository management
<a name="prepare-custom-image-repos"></a>

By default, the sample image description includes a single `<repository>` element that points to a mirror endpoint for the Amazon Linux 2023 core repositories. If needed, you can add references to other repositories from which to install your required software.

The sample image description uses the `dnf` package manager, as defined in the `<packagemanager>` element.

For more information about adding repositories, see [Setting up Repositories](https://osinside.github.io/kiwi/concept_and_workflow/repository_setup.html).

## Package management
<a name="customize-sample-ami-packages"></a>

By default, the sample image description includes all of the packages needed to create an Amazon Linux 2023 Attestable AMI for an isolated compute environment with an `erofs` read-only file system.

You can include additional software packages in the image description by adding them to the `<packages>` element in the image description. The `<packages>` element defines all of the software that should be installed into the AMI.

You can also use the `<packages>` element to uninstall or delete specific software packages.

For more information about adding or removing packages in the image description, see [Adding and Removing Packages](https://osinside.github.io/kiwi/concept_and_workflow/packages.html#).

## Adding files and directories
<a name="customize-sample-ami-overlay"></a>

The sample image description includes an overlay tree directory (`/root/`). The overlay tree directory is a directory that contains files and directories that will be copied into the image during the image build process. Any files and directories that you place into the overlay tree directory will be copied directly into the root filesystem of the image during the image building process.

The overlay tree directory is copied into the image after all the packages have been installed. New files are added and existing files are overwritten.

## Adding custom scripts
<a name="customize-sample-ami-script"></a>

The sample image description includes a single custom script, `edit_boot_install.sh`. This script includes the commands that are needed to run the `nitro-tpm-pcr-compute` utility, which generates the reference measurements based on the image content. This script is called immediately after the bootloader is installed.

If needed, you can include your own custom scripts in the image description to perform tasks or configurations during the image build process or at first boot of the image. Using scripts enables you to customize your images in ways that cannot be achieved using the image description alone.

To include custom scripts in your image description, you need to name them correctly based on the type of script, and add them to the same directory as the `appliance.kiwi` file. KIWI NG automatically detects and executes the scripts if they are named correctly and placed in the correct location, without the need to explicitly reference them in the image description file.

For more information about the scripts supported by KIWI NG, see [User-Defined Scripts](https://osinside.github.io/kiwi/concept_and_workflow/shell_scripts.html).

# Compute PCR measurements for a custom AMI
<a name="create-pcr-compute"></a>

The `nitro-tpm-pcr-compute` utility enables you to generate the reference measurements for an Attestable AMI during build time based on its Unified Kernel Image (UKI).

The sample Amazon Linux 2023 image description automatically installs the utility in the built image in the `/usr/bin/` directory. The sample image description also includes a script with the commands needed to run the utility to generate the reference measurements during image build time. If you are using the sample image description, you don't need to install the utility or run it manually. For more information, see [Build the sample Amazon Linux 2023 image description](build-sample-ami.md).

## Install the `nitro-tpm-pcr-compute` utility
<a name="nitro-tpm-compute-install"></a>

If you are using Amazon Linux 2023, you can install the `nitro-tpm-pcr-compute` utility from the Amazon Linux repository as follows.

```
sudo yum install aws-nitro-tpm-tools
```

The tools are installed in the `/usr/bin` directory.

## Use the `nitro-tpm-pcr-compute` utility
<a name="nitro-tpm-compute-use"></a>

The utility provides a single command, `nitro-tpm-pcr-compute`, for generating the reference measurements.

When you run the command, you must specify the following:
+ Unified kernel image (`UKI.efi`) — Required for Standard boot and UEFI.

**To generate the reference measurements for an Attestable AMI:**  
Use the following command and parameters:

```
/usr/bin/nitro-tpm-pcr-compute \
--image UKI.efi
```

The utility returns the reference measurements in the following JSON format:

```
{
  "Measurements": {
    "HashAlgorithm": "SHA384 { ... }",
    "PCR4": "PCR4_measurement",
    "PCR7": "PCR7_measurement",
    "PCR12": "PCR12_measurement"
  }
}
```

For a practical example of how to use the `nitro-tpm-pcr-compute` utility, see the `edit_boot_install.sh` script included in the [ sample Amazon Linux 2023 image description](build-sample-ami.md).