Build AWS Nitro Enclave confidential computing environments using nitro-cli to create enclave images, configure attestation-aware KMS policies with PCR condition keys, validate attestation documents against the Nitro PKI root, and set up vsock/kmstool-enclave-cli pipelines for processing PII, keys, and health records. Use for Nitro Enclave setup, attestation validation, or scoping KMS to an enclave image hash.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Build AWS Nitro Enclave confidential computing environments using nitro-cli to create enclave images, configure attestation-aware KMS policies with PCR condition keys, validate attestation documents against the Nitro PKI root, and set up vsock/kmstool-enclave-cli pipelines for processing PII, keys, and health records. Use for Nitro Enclave setup, attestation validation, or scoping KMS to an enclave image hash.
Processing sensitive data (PII, PHI, financial records, cryptographic secrets) that must be isolated from EC2 instance operators and administrators
Building confidential computing pipelines where even root-level access on the parent instance cannot read enclave memory or state
Implementing cryptographic attestation workflows that tie KMS decryption rights to a specific, verified enclave image hash
Deploying multi-party computation environments where two or more enclaves authenticate each other via attestation before exchanging data
Hardening existing workloads that currently decrypt secrets on the parent instance by migrating decryption into an enclave boundary
Do not use when the workload does not handle sensitive data that requires hardware-level isolation, when the instance type does not support Nitro Enclaves (requires Nitro-based instances with at least 4 vCPUs), or when latency constraints make the vsock communication overhead unacceptable.
Prerequisites
An AWS account with permissions to launch Nitro-capable EC2 instances (m5.xlarge or larger, C5, R5, M6i families)
AWS CLI v2 and the nitro-cli toolset installed on the parent EC2 instance (Amazon Linux 2 or AL2023)
Docker installed on the parent instance for building enclave image files (EIF)
An AWS KMS symmetric key with key policy permissions for the enclave's IAM role
The aws-nitro-enclaves-sdk-c or Python aws-encryption-sdk for enclave-side KMS operations
The Nitro Enclaves allocator service configured with sufficient memory and vCPU allocation in /etc/nitro_enclaves/allocator.yaml
Workflow
Step 1: Configure the Nitro Enclaves Environment
Set up the parent EC2 instance to support enclave launches:
Install the Nitro Enclaves CLI: On Amazon Linux 2, install the tools and allocator:
Configure memory and CPU allocation: Edit to reserve resources for the enclave. The enclave requires dedicated memory that is carved from the parent instance:
Restart the allocator:
Verify setup: Run nitro-cli describe-enclaves to confirm the CLI can communicate with the Nitro hypervisor. An empty JSON array [] indicates no enclaves are running and the setup is correct.
Step 2: Build the Enclave Image File (EIF)
Package the sensitive workload into a signed enclave image:
Create the application Dockerfile: The enclave runs a minimal Linux environment. The application communicates exclusively through vsock:
PCR8 (the signing certificate hash) enables KMS policies that trust any image signed by a specific certificate, allowing image updates without changing the policy.
Multi-PCR policy for defense in depth: Combine PCR0 (image) and PCR1 (kernel) to ensure both the application and the boot environment match expected values:
IAM role policy: The parent instance's IAM role must have kms:Decrypt permission, but the KMS key policy condition ensures the actual decryption only succeeds when the request originates from a valid enclave with the correct attestation document attached.
Step 4: Implement Secure Vsock Communication
Establish the parent-to-enclave communication channel:
Vsock architecture: The only way an enclave communicates with the outside world is through a vsock (virtual socket). Vsock uses a CID (Context Identifier) and port number. The parent instance CID is always 3, and the enclave CID is assigned at launch.
Parent-side proxy server: The parent runs a proxy that forwards KMS API calls from the enclave through the vsock to the AWS KMS endpoint:
Enclave-side client: The enclave application requests an attestation document from the Nitro Security Module (NSM) device at /dev/nsm, attaches it to KMS decrypt requests, and receives data encrypted to the enclave's ephemeral public key:
import socket
import json
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes, serialization
PARENT_CID = 3
VSOCK_PORT = 5000defget_attestation_document(public_key_der):
"""Request attestation document from NSM device."""# Uses the aws-nitro-enclaves-nsm-api# NSM provides: module_id, digest (SHA384), timestamp, PCRs,# certificate (from Nitro PKI), cabundle, public_key, user_data, nonceimport nsm_util
nsm_fd = nsm_util.nsm_lib_init()
attestation_doc = nsm_util.nsm_get_attestation_doc(
nsm_fd,
public_key=public_key_der,
user_data=None,
nonce=None
)
return attestation_doc
defdecrypt_via_parent(ciphertext_hex):
"""Send decrypt request through vsock to parent proxy."""
private_key = rsa.generate_private_key(
public_exponent=65537, key_size=2048
)
public_key_der = private_key.public_key().public_bytes(
serialization.Encoding.DER,
serialization.PublicFormat.SubjectPublicKeyInfo
)
attestation_doc = get_attestation_document(public_key_der)
sock = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM)
sock.connect((PARENT_CID, VSOCK_PORT))
sock.sendall(json.dumps({
'action': 'decrypt',
'ciphertext': ciphertext_hex,
'attestation_doc': attestation_doc.hex()
}).encode())
response = json.loads(sock.recv(65536).decode())
sock.close()
# KMS encrypted the plaintext to the enclave's public key# Only the enclave's private key can decrypt it
ciphertext_for_recipient = bytes.fromhex(
response['ciphertext_for_recipient']
)
plaintext = private_key.decrypt(
ciphertext_for_recipient,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return plaintext
Step 5: Validate Attestation Documents
Verify attestation documents from enclaves to establish trust:
Attestation document structure: The document is CBOR-encoded and COSE-signed (COSE_Sign1). It contains:
module_id: Identifier for the NSM module
digest: Hashing algorithm (SHA-384)
timestamp: Unix epoch milliseconds when the document was created
pcrs: Map of PCR index to measurement value (PCR0-PCR15)
certificate: The NSM's x509 certificate, signed by the Nitro PKI
cabundle: Certificate chain from the NSM certificate to the AWS Nitro root CA
public_key: The enclave's ephemeral public key (provided at attestation request time)
user_data: Optional application-defined data (up to 512 bytes)
nonce: Optional nonce for freshness verification
Validation steps:
Decode the COSE_Sign1 structure and extract the payload and certificate
Verify the COSE signature using the public key from the embedded certificate
Validate the certificate chain from the NSM certificate through the CA bundle to the AWS Nitro Attestation PKI root certificate (available at https://aws-nitro-enclaves.amazonaws.com/AWS_NitroEnclaves_Root-G1.zip)
Check that the root CA certificate matches the expected AWS root: aws.nitro-enclaves CN
Verify that no certificate in the chain is expired at the document's timestamp
Compare PCR0, PCR1, PCR2 values against expected measurements from the enclave build output
If a nonce was provided, verify it matches to prevent replay attacks
Attestation validation code:
import cbor2
from cose import CoseMessage
from cryptography import x509
from cryptography.x509.oid import NameOID
defvalidate_attestation(attestation_bytes, expected_pcrs, expected_nonce=None):
cose_msg = CoseMessage.decode(attestation_bytes)
payload = cbor2.loads(cose_msg.payload)
# Verify certificate chain
cert = x509.load_der_x509_certificate(payload['certificate'])
cabundle = [x509.load_der_x509_certificate(c) for c in payload['cabundle']]
# Check root CA is AWS Nitro
root = cabundle[-1]
cn = root.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value
assert cn == 'aws.nitro-enclaves', f'Unexpected root CA: {cn}'# Verify PCR measurements
pcrs = payload['pcrs']
for idx, expected_value in expected_pcrs.items():
actual = pcrs.get(idx, b'').hex()
assert actual == expected_value, f'PCR{idx} mismatch: {actual}'# Verify nonce freshnessif expected_nonce:
assert payload.get('nonce') == expected_nonce, 'Nonce mismatch'return payload
Step 6: Launch and Monitor the Enclave
Run the enclave and implement operational monitoring:
Note: --debug-mode enables the enclave console for development. Remove it in production as it allows reading enclave output, which breaks the isolation guarantee.
Verify enclave status:
nitro-cli describe-enclaves
Expected output includes "State": "RUNNING", the assigned EnclaveCID, memory, CPU count, and enclave flags.
CloudWatch monitoring: Configure the parent instance to report enclave health metrics. Since the enclave has no network access, health checks must go through the vsock proxy:
An isolated virtual machine created by the Nitro Hypervisor on a Nitro-based EC2 instance with no persistent storage, no network access, and no interactive access, even from the parent instance's root user
Attestation Document
A CBOR-encoded, COSE-signed document generated by the Nitro Security Module containing PCR measurements, a certificate chain to the AWS Nitro root CA, and optional user-provided data
PCR (Platform Configuration Register)
SHA-384 hash measurements that uniquely identify an enclave's image (PCR0), kernel/bootstrap (PCR1), application (PCR2), IAM role (PCR4), instance ID (PCR3), and signing certificate (PCR8)
Vsock
A virtual socket providing the sole communication channel between a parent EC2 instance and its enclave, using CID (Context Identifier) and port addressing
EIF (Enclave Image File)
The packaged enclave image built by nitro-cli from a Docker image, containing the kernel, ramdisk, and application, producing PCR measurements at build time
Nitro Security Module (NSM)
A custom Linux device (/dev/nsm) inside the enclave that provides attestation document generation and hardware random number generation
COSE_Sign1
CBOR Object Signing and Encryption single-signer structure used to sign the attestation document with the NSM's private key
kms:RecipientAttestation
AWS KMS condition key prefix that enables key policies to enforce that decrypt/generate operations only succeed when a valid attestation document with matching PCR values is presented
Tools & Systems
nitro-cli: AWS CLI tool for building enclave image files, launching/terminating enclaves, and reading enclave console output
AWS KMS: Key Management Service that natively supports attestation-based condition keys for Nitro Enclaves, encrypting responses to the enclave's ephemeral public key
aws-nitro-enclaves-sdk-c: C SDK for enclave-side KMS operations that handles attestation document generation and vsock proxy communication
kmstool-enclave-cli: Pre-built CLI tool (from the SDK) that runs inside the enclave to perform KMS Decrypt and GenerateRandom operations with attestation
Nitro Enclaves ACM: AWS Certificate Manager integration that provisions TLS certificates inside enclaves for establishing HTTPS endpoints
CloudTrail: Logs KMS API calls including Decrypt and GenerateDataKey operations that include Recipient parameters, enabling auditing of enclave-originated cryptographic operations
Common Scenarios
Scenario: Implementing a PII Tokenization Service in a Nitro Enclave
Context: A healthcare SaaS company processes patient records containing PHI. Regulations require that the decryption and tokenization of PHI never occurs on an instance accessible to operators. The company deploys a Nitro Enclave that receives encrypted patient records, decrypts them inside the enclave using KMS with attestation, tokenizes the PII fields, and returns only the tokenized records through the vsock.
Approach:
Build the tokenization application into a Docker image containing the tokenization logic, the kmstool-enclave-cli binary, and a vsock server that accepts encrypted records
Build the EIF with nitro-cli build-enclave and record PCR0, PCR1, PCR2 from the build output
Create a KMS key with a key policy that includes a kms:RecipientAttestation:ImageSha384 condition matching PCR0, allowing only this specific enclave build to decrypt patient records
Deploy the parent instance with an IAM role that has kms:Decrypt on the key, but the KMS condition ensures decryption only succeeds inside the attested enclave
The parent application receives encrypted patient records over HTTPS, passes them to the enclave over vsock port 5000, and receives tokenized records back
The enclave requests an attestation document from the NSM, attaches it to the KMS Decrypt call, receives the plaintext encrypted to its ephemeral RSA key, decrypts locally, tokenizes PII (SSN, DOB, name), and returns {ssn: "tok_a8f3...", dob: "tok_b2e1...", name: "tok_c9d4..."}
CloudTrail logs show Decrypt calls with RecipientAttestation parameters, confirming all decryption occurs within the enclave boundary
Pitfalls:
Running the enclave in debug mode in production, which allows console access and breaks the confidentiality guarantee that regulators require
Setting the KMS key policy to use only the IAM role without attestation conditions, which allows the parent instance to decrypt directly without the enclave
Failing to reserve sufficient memory in allocator.yaml, causing the enclave to fail at launch with an opaque "resource not available" error
Not implementing vsock message framing, causing large records to be truncated at the 64KB socket buffer boundary
Forgetting that PCR0 changes with every code rebuild, requiring a KMS policy update for each deployment; use PCR8 (signing certificate) for production to decouple builds from policy updates
Output Format
## Nitro Enclave Security Assessment
**Enclave Image**: enclave-tokenizer.eif
**Build Date**: 2026-03-19T14:30:00Z
**Instance Type**: m5.2xlarge
**Allocated Resources**: 2 vCPUs, 4096 MiB memory
### PCR Measurements
| PCR | Value | Bound in KMS Policy |
|-----|-------|---------------------|
| PCR0 (Image) | a1b2c3d4e5f6... | Yes |
| PCR1 (Kernel) | f6e5d4c3b2a1... | Yes |
| PCR2 (Application) | 1a2b3c4d5e6f... | No |
| PCR8 (Signing Cert) | 9f8e7d6c5b4a... | Yes (production) |
### KMS Key Policy Verification
- Key ARN: arn:aws:kms:us-east-1:111122223333:key/mrk-abc123
- Attestation condition: kms:RecipientAttestation:ImageSha384 = PCR0
- Signing cert condition: kms:RecipientAttestation:PCR8 = <cert-hash>
- Parent role: arn:aws:iam::111122223333:role/EnclaveParentRole
- Direct decrypt from parent: BLOCKED (attestation required)
- Decrypt from verified enclave: ALLOWED
### Security Posture
- [PASS] Debug mode disabled in production launch command
- [PASS] Vsock is the only communication channel (no network interface)
- [PASS] Attestation document nonce verification implemented
- [PASS] Certificate chain validates to AWS Nitro root CA
- [WARN] PCR0 used in policy; consider PCR8 for deployment flexibility
- [FAIL] Health check endpoint does not verify enclave attestation freshness