Attestation with Anjuna for AWS Nitro Enclaves
This section is a conceptual overview of how attestation, a critical security feature, is used in AWS Nitro Enclaves and the Anjuna Nitro Runtime.
Attestation for AWS Nitro Enclaves
Secure enclaves have the ability to generate an attestation document, a piece of data which cryptographically proves that an enclave is running with particular code inside.
Applications running in AWS Nitro Enclaves can request a signed attestation document from the AWS Nitro Hypervisor. An attestation document consists of two main components: an attestation key signature from the secure enclave platform, and the measurements of the enclave.
Attestation document components
Attestation key signature
The attestation document contains a signature created by the secure enclave hardware platform’s attestation key. This cryptographic signing key is a private key in the enclave platform, in this case AWS Nitro. The secure enclave hardware enforces that this key is only accessible from legitimate secure enclaves.
A client can validate the signature on the attestation document using the corresponding public key, which is provided by the enclave platform operator, AWS. For instructions, see AWS documentation: Verifying the root of trust for AWS Nitro Enclaves.
An attestation document with a valid signature must originate from a secure enclave, because only secure enclaves have access to an attestation key. If any part of the attestation document has been modified, the signature will fail to validate because it was only valid for the original content. This means that it is not possible for an attacker to forge a fraudulent attestation document.
Measurements
Conceptually, a measurement is a cryptographic hash of the contents of an enclave. Because the entire enclave contents are an input to the hash function, if any part of the enclave changes - even a single bit in your code - the measurement will completely change. You can think of the measurements as a set of “fingerprints” for the identity of the enclave.
AWS Nitro Enclaves generate measurements for different parts of the enclave, like the full enclave, the IAM role for the instance, or a user-provided signing key. These measurements are stored in platform configuration registers (PCRs). See AWS documentation for descriptions of the different PCRs available for AWS Nitro Enclaves.
The following table describes the measurements (or "PCR values") included in the attestation document:
PCR | Hash of | Description |
---|---|---|
PCR0 |
Enclave image file |
A contiguous measure of the contents of the image file, without the section data. |
PCR1 |
Linux kernel and bootstrap |
A contiguous measurement of the kernel and boot ramfs data. |
PCR2 |
Application |
A contiguous, in-order measurement of the user applications, without the boot ramfs . |
PCR3 |
IAM role assigned to the parent instance |
A contiguous measurement of the IAM role assigned to the parent instance. Ensures that the attestation process succeeds only when the parent instance has the correct IAM role. |
PCR4 |
Instance ID of the parent instance |
A contiguous measurement of the ID of the parent instance. Ensures that the process succeeds only when the parent instance has a specific instance ID. |
PCR8 |
Enclave image file signing certificate |
A measure of the signing certificate specified for the enclave image file. Ensures that the attestation process succeeds only when the enclave was booted from an enclave image file signed by a specific certificate. |
A policy using any combinations of the PCR values above can be created to precisely define the enclaves that are allowed to perform operations on a specific AWS KMS key object.
AWS KMS integration
An authorized user can attach a policy to a specific AWS KMS key and restrict the usage of that key to AWS Nitro Enclaves with specific measurements. This mechanism ensures that sensitive data, when encrypted by correctly-configured AWS KMS keys, can only be decrypted by approved applications running in AWS Nitro Enclaves.
The following diagram shows three different applications trying to access a key in AWS KMS. After a cloud administrator in your organization configures the key to require attestation, AWS KMS will only grant access to your specific application running in an AWS Nitro Enclave.
Anjuna Nitro Runtime boot-time secrets
The Anjuna Nitro Runtime builds on the AWS KMS integration for Nitro Enclaves to securely deliver secrets to your application at boot time. No changes to the application code are needed to use this feature.
At boot time, the Anjuna Nitro Runtime fetches the "Encrypted Configuration”, which is stored in an S3 bucket or local file. It is decrypted using an AWS KMS key that only the enclave can access. Then, the contents of the encrypted configuration are injected into the enclave as environment variables or files.
Each step in this process is protected by various forms of encryption, so the secret is never accessible by AWS or any party outside of the enclave. TLS 1.2 is used to protect data in transit. Additionally, client-side encryption ensures that the plaintext data is never visible to AWS or any other party outside of the enclave.
Using the Anjuna Nitro Runtime for this capability is more secure than traditional secret delivery using regular IAM policies and IAM roles. Consider a scenario where an attacker gains access to your application’s EC2 instance. If your application uses a service like AWS Secrets Manager, authenticated using only the IAM role, the attacker has the same permissions and is able to exfiltrate secrets. If your application uses the Anjuna Nitro Runtime boot-time secrets, the attacker is unable to generate a valid attestation quote, so they cannot exfiltrate those secrets - even though they have access to the parent instance and its IAM role.
Setting up an encrypted configuration
Anjuna provides a tool, anjuna-nitro-encrypt
, which encrypts a configuration file and
uploads the encrypted blob to an S3 bucket or stores it to a local file.
It uses the Amazon S3 Encryption Client to perform client-side encryption, which ensures that the plaintext data is never visible to AWS or entities with access to the S3 bucket or local data file.
The following diagram shows how the client-side encryption (sometimes called “envelope encryption”) works:
The final encrypted blob is what is uploaded to the S3 bucket or alternatively stored to a local file.
After creating and uploading the blob, you can add its S3 URI to the uri
of a s3
type encryptedConfig
entry of
the enclave configuration file and build an Enclave Image File (EIF).
You can set uri even if the S3 object does not exist yet,
as long as the S3 object exists when you start the enclave.
|
Once you have an EIF, you can take its measurements and use them to restrict the usage of the AWS KMS key to only this specific enclave.
Sequence diagram at boot time
At boot time, the Anjuna Nitro Runtime fetches the encrypted configuration file from S3, generates an attestation quote, decrypts the encrypted configuration file, and injects the given configuration to the container instance.
In the diagram below, E_k
represents encryption with key k
,
and x || y
represents the concatenation of x
and y
.