How Does Cryptographic Attestation Work in AWS Nitro Enclaves?
AWS Nitro Enclaves verify their identity and software integrity using a hardware-rooted cryptographic attestation mechanism powered by the AWS Nitro System. At the core of this process is a cryptographically signed Attestation Document generated by the Nitro Hypervisor, which contains Platform Configuration Registers, a public key certificate chain rooted in the AWS Nitro Attestation Public KeyInfrastructure, and optional user-supplied cryptographic material such as nonces and asymmetric public keys. External services and AWS Key Management Service validate this CBOR-encoded and COSE-signed document to confirm that an enclave runs an exact, unmodified Enclave Image File before releasing sensitive data or decryption keys.
The Role of the AWS Nitro Hypervisor in Attestation
AWS Nitro Enclaves are isolated compute environments carved out of
the CPU and memory resources of a parent Amazon EC2 instance. Because an
enclave has no persistent storage, no interactive administrator access,
and no external networking (communicating only with the parent instance
over a local virtual socket, or vsock), proving its
trustworthiness to external systems requires hardware-backed
cryptographic verification.
The root of trust for an enclave is the AWS Nitro System hardware and
firmware, specifically the Nitro Security Chip and the Nitro Hypervisor.
When an enclave is launched from an Enclave Image File (EIF), the Nitro
Hypervisor computes cryptographic measurements of the image's
components, signing certificates, and runtime state. When the
application inside the enclave requests an attestation document via the
/dev/nsm (Nitro Secure Module) device driver, the
hypervisor constructs and signs the document using a private key tightly
bound to the underlying physical Nitro hardware.
Platform Configuration Registers (PCRs)
Platform Configuration Registers (PCRs) are cryptographic digests computed using the \(\text{SHA-384}\) hash algorithm. Similar to Trusted Platform Module (TPM) registers, each PCR in a Nitro Enclave measures a distinct aspect of the enclave's boot environment and identity.
When an enclave image is built using the
nitro-cli build-enclave command, the CLI outputs expected
\(\text{SHA-384}\) measurements. At
runtime, the Nitro Hypervisor independently calculates these hashes and
populates the attestation document with the following PCR values:
- PCR0 (Enclave Image File Measurement): A contiguous hash of the entire Enclave Image File, encompassing the kernel, ramdisk, and application container image. Any modification to a single byte of the application code or dependencies alters \(\text{PCR}_0\).
- PCR1 (Linux Kernel and Bootstrap Measurement): A hash of the Linux kernel and the initial boot ramfs used to initialize the enclave environment.
- PCR2 (Application Measurement): A hash specifically measuring the user-space application and customer payload without the operating system kernel.
- PCR3 (Parent Instance IAM Role): A hash of the AWS Identity and Access Management (IAM) role assigned to the parent Amazon EC2 instance.
- PCR4 (Parent Instance ID): A hash of the unique Amazon EC2 instance ID of the parent host.
- PCR8 (Enclave Signing Certificate): A hash of the
X.509 signing certificate provided during the
nitro-cli build-enclaveprocess if the enclave image was cryptographically signed by the author.
When an enclave boots in Debug Mode (configured via
the --debug-mode flag for troubleshooting console output),
the Nitro Hypervisor intentionally zeroes out all PCR measurements
(setting every byte to 0x00). This ensures that a debugging
enclave can never masquerade as a production enclave or pass
cryptographic verification checks against production PCR policies.
Structure of the Nitro Attestation Document
The attestation document returned by the Nitro Secure Module is formatted using CBOR (Concise Binary Object Representation, RFC 8949) and wrapped in a COSE_Sign1 (CBOR Object Signing and Encryption, RFC 8152) digital signature structure using the \(\text{ECDSA}\) algorithm over the P-384 elliptic curve (\(\text{ES384}\)).
Inside the signed CBOR payload, the document contains the following fields:
module_id: A unique identifier for the specific Nitro Enclave instance.timestamp: The Unix epoch time (in milliseconds) when the Nitro Hypervisor generated the document.digest: The hash function used for PCR calculations, which is always"SHA384".pcrs: A map of PCR indices (\(0\) through \(15\)) to their 48-byte \(\text{SHA-384}\) binary values: \[\text{PCR}_i = \text{SHA-384}(\text{Component}_i) \in \{0, 1\}^{384}\]certificate: The DER-encoded X.509 public key certificate corresponding to the private key the local Nitro Hypervisor used to sign this specific attestation document.cabundle: An ordered array of intermediate CA certificates leading up to the root AWS Nitro Enclaves Root-G1 certificate for that AWS Region.public_key: An optional byte string containing an ephemeral asymmetric public key (such as an RSA-2048/4096 or ECDH public key) generated inside the enclave's memory.user_data: An optional byte string carrying application-specific arbitrary metadata.nonce: An optional cryptographic nonce provided by the relying party or enclave to prevent replay attacks.
Cryptographic Verification Workflow
A relying party—whether a custom third-party verification server or an integrated AWS service—executes a multi-step cryptographic validation process to verify an enclave's identity:
1. COSE Signature and PKI Chain Validation
First, the verifier parses the COSE_Sign1 structure and
extracts the leaf certificate and cabundle
from the payload. The verifier validates the X.509 certificate chain up
to the published AWS Nitro Enclaves Root-G1 root
certificate using standard PKI path validation rules:
\[\text{VerifyChain}(\text{Root CA} \rightarrow \text{Intermediate CAs} \rightarrow \text{Enclave Leaf Certificate})\]
This step includes checking certificate validity windows against the current time. Once the leaf certificate is trusted as genuine AWS Nitro hardware, the verifier uses the leaf certificate's public key (\(PK_{\text{leaf}}\)) to verify the \(\text{ES384}\) digital signature over the CBOR payload.
2. Freshness and Replay Protection
To ensure the attestation document was not captured and replayed from
an earlier session, the verifier inspects the timestamp
field and verifies that the nonce field matches the
cryptographic challenge originally issued to the enclave.
3. PCR Policy Evaluation
The verifier compares the PCR values inside the signed document against an allowlist of known-good reference values. Most organizations enforce checks on \(\text{PCR}_0\) (to lock down the exact build artifact) or a combination of \(\text{PCR}_1\), \(\text{PCR}_2\), and \(\text{PCR}_8\) (which allows updating the enclave image without changing IAM policies, provided the image is signed by the trusted developer certificate hashed in \(\text{PCR}_8\)).
4. Ephemeral Key Binding and Secure Channel Establishment
Because an enclave has no persistent storage, it cannot store static TLS private keys on disk without exposing them in the unencrypted EIF image. Instead, upon boot, the enclave generates an ephemeral key pair \((SK_{\text{enclave}}, PK_{\text{enclave}})\) strictly inside its isolated RAM. It passes \(PK_{\text{enclave}}\) into the NSM attestation request. When the relying party verifies the attestation document signature, it obtains cryptographic proof that \(PK_{\text{enclave}}\) resides inside a genuine Nitro Enclave matching the expected PCRs. The relying party can then encrypt sensitive secrets using \(PK_{\text{enclave}}\):
\[C = \text{Encrypt}_{PK_{\text{enclave}}}(\text{Secret})\]
Only the attested enclave holding \(SK_{\text{enclave}}\) in isolated memory can decrypt the ciphertext \(C\).
Native Integration with AWS Key Management Service (KMS)
AWS KMS provides native support for Nitro Enclave attestation, acting
as a built-in relying party. When an enclave calls KMS APIs
(Decrypt, DeriveSharedSecret,
GenerateDataKey, GenerateDataKeyPair, or
GenerateRandom), it can include its signed attestation
document in the Recipient parameter of the API request,
alongside an ephemeral RSA public key stored in the attestation
document's public_key field.
KMS evaluates the attestation document against IAM Condition Keys defined on the KMS Key Policy:
kms:RecipientAttestation:ImageSha384: Matches \(\text{PCR}_0\)kms:RecipientAttestation:PCR0throughkms:RecipientAttestation:PCR15: Matches the corresponding PCR index
An example KMS Key Policy statement restricting key decryption to a verified enclave image looks like this:
{
"Sid": "AllowEnclaveDecryptWithAttestation",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/EnclaveParentInstanceRole"
},
"Action": "kms:Decrypt",
"Resource": "*",
"Condition": {
"StringEqualsIgnoreCase": {
"kms:RecipientAttestation:PCR0": "a1b2c3d4e5f6...96-hex-character-sha384-hash..."
}
}
}When the parent instance's IAM role makes the
kms:Decrypt call through the vsock proxy on
behalf of the enclave:
- AWS KMS verifies the Nitro PKI certificate chain and the
COSE_Sign1signature of the attestation document. - AWS KMS checks that the \(\text{PCR}_0\) value in the document
matches the
kms:RecipientAttestation:PCR0condition in the key policy. - Instead of returning the plaintext data key in the standard API
response—which the untrusted parent EC2 instance could intercept over
vsock—KMS re-encrypts the plaintext response under the enclave's ephemeral RSA public key (\(PK_{\text{enclave}}\)) using \(\text{RSAES-OAEP-SHA-256}\) and returns it in theCiphertextForRecipientfield. - Only the enclave possesses the corresponding private key (\(SK_{\text{enclave}}\)) in its isolated
memory to decrypt
CiphertextForRecipient, guaranteeing end-to-end confidentiality between AWS KMS and the enclave runtime.