Lesson 4.2 · 16 min read
Measurements and attestation documents
The six PCRs, the CBOR/COSE attestation document, and how to verify it.
The six measurements
Nitro Enclaves use SHA-384 platform configuration registers (PCRs). Building an enclave image file (EIF) with nitro-cli build-enclave prints PCR0, PCR1 and PCR2. The others are derived from the parent instance or signing certificate.
| PCR | Measures | Use in policy |
|---|---|---|
| PCR0 | The enclave image file (without section metadata) | Pin an exact image; equals the attestation ImageSha384 value in KMS |
| PCR1 | Linux kernel and bootstrap | Pin the enclave kernel |
| PCR2 | The user application | Pin the application layer |
| PCR3 | IAM role ARN of the parent instance | Only enclaves on instances with the right role |
| PCR4 | Instance ID of the parent instance | Only enclaves on one specific instance |
| PCR8 | The EIF signing certificate | Trust any image signed by your certificate |
AWS recommends using PCR3 and PCR8 together for flexibility: policies keep working when you rebuild the image (as long as you sign it) or replace the instance (as long as it has the same role).
# PCR3 is SHA-384 over 48 zero bytes followed by the role ARN (AWS-documented method)
ROLEARN="arn:aws:iam::123456789012:role/Webserver"
python3 -c "import hashlib; h=hashlib.sha384(); h.update(b'\0'*48); h.update('$ROLEARN'.encode()); print(h.hexdigest())"The attestation document
Inside the enclave, the application asks the Nitro Secure Module (NSM) for an attestation document. The document is CBOR-encoded and signed as a COSE_Sign1 structure using ECDSA with P-384. Its payload includes:
| Field | Content |
|---|---|
module_id | ID of the issuing Nitro Hypervisor module |
timestamp | UTC time in milliseconds when the document was created |
digest | The digest algorithm, SHA384 |
pcrs | Map of PCR index to value |
certificate and cabundle | Signing certificate and the chain up to the AWS Nitro Enclaves root |
public_key | Optional key supplied by the enclave; KMS encrypts responses to it |
user_data, nonce | Optional application data and a verifier nonce |
Verifying a document yourself
- Decode the COSE_Sign1 and CBOR payload.
- Validate the certificate chain from
cabundleto the AWS Nitro Enclaves root certificate, whose fingerprint AWS publishes. - Verify the COSE signature with the leaf certificate's key.
- Check PCR values against approved reference values, and the nonce and timestamp for freshness.
- Use
public_keyfrom the document, never a key sent separately, to encrypt anything for the enclave.
Key takeaways
- PCR0/1/2 come from the EIF build; PCR3/4 bind to the parent's role and instance; PCR8 binds to the signing certificate.
- Attestation documents are CBOR inside COSE_Sign1, chained to the AWS Nitro Enclaves root.
- All-zero PCRs mean debug mode: reject them.
Sources: Cryptographic attestation (AWS), Attestation process (AWS, GitHub), Verifying the root of trust (AWS).