Skip to content

[Guardian] Verify Nitro enclave attestation + pin PCR0#666

Open
mskd12 wants to merge 8 commits into
mainfrom
deepakmaram/guardian-attestation-verify
Open

[Guardian] Verify Nitro enclave attestation + pin PCR0#666
mskd12 wants to merge 8 commits into
mainfrom
deepakmaram/guardian-attestation-verify

Conversation

@mskd12

@mskd12 mskd12 commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

⚠️ Do not merge until fastcrypto PR MystenLabs/fastcrypto#971 lands. We pin fastcrypto to its nitro-attestation branch tip here; once #971 merges we repoint to the exact merged commit hashes (fastcrypto + fastcrypto-tbls) so the dependency is on a stable rev, not a moving branch.

Turns verify_enclave_attestation from a no-op into real AWS Nitro verification, and pins PCR0 from config.

Verify

  • parse_nitro_attestationverify_nitro_attestation (fastcrypto nitro_attestation): COSE_Sign1 signature + X.509 cert chain to the AWS Nitro root, freshness against now_timestamp_ms() (the API takes millis).
  • Anchors doc.public_key == signing_pubkey (the enclave binds its signing key into the attestation).
  • Pins fastcrypto to the nitro-attestation branch tip (prior rev + that module; safe superset).

PCR0 pinning

  • BuildPcrs — one build's PCR set — mandates PCR0 at construction (BuildPcrs::new(pcr0), no empty/Default), so a pinning policy can't omit it. verify_enclave_attestation pins doc.pcr_map[0] against it.
  • We record only PCR0: in a StageX (reproducible, single-binary) build it's the only measurement that carries signal; the others (kernel, bootloader, IAM role) are constant or irrelevant.
  • Threaded source → sink: an expected_pcr0 config field → GuardianReader::newGuardianSessionKeyCacheget_verified_enclave_pubkey, plus GetGuardianInfoResponse::verify(&BuildPcrs) for the relay path. Mandatory for all readers — both the provisioner and the monitor auditor supply expected_pcr0 (configs + sample YAMLs + README updated).

Dev/test

Gated cfg(any(test, feature = "non-enclave-dev")) → no-op for the mock enclave; the flag propagates from hashi-guardian's non-enclave-dev to hashi-types/non-enclave-dev, so e2e needs no change. Prod enables neither → real verification + PCR0 pinning.

Follow-up

BuildPcrs holds a single PCR set, so it doesn't yet accept the two valid measurements that coexist during a software upgrade. The next PR adds a commit → BuildPcrs allowlist keyed on untrusted_git_revision (TODOs left on BuildPcrs and s3_reader).

🤖 Generated with Claude Code

mskd12 and others added 2 commits June 5, 2026 19:10
…ey anchor)

`verify_enclave_attestation` now actually verifies the AWS Nitro attestation via
fastcrypto's `nitro_attestation` module instead of being a no-op:

- parse + verify the COSE_Sign1 signature and the X.509 cert chain to the AWS
  Nitro root, freshness checked against now (ms).
- anchor the document's `public_key` to the session signing pubkey — the enclave
  binds its signing key into the attestation.

Gated behind `non-enclave-dev` (+ cfg(test)) so off-enclave/dev/e2e builds, which
run a mock enclave, accept the stub document; the feature propagates from
hashi-guardian's existing `non-enclave-dev`. Pins fastcrypto to the
`nitro-attestation` branch.

TODO(check C): pin the document's PCRs against an expected set.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`ExpectedPcrs` mandates PCR0 at construction (`ExpectedPcrs::new`), and is
threaded from config to `verify_enclave_attestation`, which pins the
attestation's PCR0 (the EIF image hash) after the COSE/cert/pubkey checks:

- source -> sink: an `expected_pcr0` config field -> `GuardianReader::new` ->
  `GuardianSessionKeyCache` -> `get_verified_enclave_pubkey`, plus
  `GetGuardianInfoResponse::verify(&ExpectedPcrs)` for the relay path.
- Both the provisioner (`ProvisionerConfig`) and the monitor auditor
  (`hashi-monitor` `Config`) supply `expected_pcr0`; sample YAMLs + README updated.

A single mandatory PCR0 for now; accepting multiple measurements during a
software upgrade is a follow-up (TODO on `ExpectedPcrs`).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mskd12 mskd12 force-pushed the deepakmaram/guardian-attestation-verify branch from 0e8ac5e to 293abf5 Compare June 6, 2026 06:06
@mskd12 mskd12 changed the title [Guardian] Verify Nitro enclave attestation + pin PCRs [Guardian] Verify Nitro enclave attestation + pin PCR0 Jun 6, 2026
mskd12 and others added 5 commits June 9, 2026 15:17
- Drop needless `return` in verify_enclave_attestation dev stub (clippy).
- Add expected_pcr0 to the two hashi-monitor test Config literals.
- Commit the hex Cargo.lock entry for hashi-monitor (docs is-dirty).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…attestation-verify

# Conflicts:
#	crates/hashi-guardian-init/src/provisioner.rs
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A build's measurement set is the durable concept; the future commit->PCRs
allowlist will be a separate type keyed on untrusted_git_revision.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mskd12 mskd12 marked this pull request as ready for review June 9, 2026 23:07
@mskd12 mskd12 requested a review from bmwill as a code owner June 9, 2026 23:07
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant