Add teeattestation package for TEE attestation validation#1899
Add teeattestation package for TEE attestation validation#1899
Conversation
|
👋 nadahalli, thanks for creating this pull request! To help reviewers, please consider creating future PRs as drafts first. This allows you to self-review and make any final changes before notifying the team. Once you're ready, you can mark it as "Ready for review" to request feedback. Thanks! |
0ea8118 to
2edce5f
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new teeattestation package providing platform-agnostic domain-separated hashing and AWS Nitro Enclave attestation validation, along with a fake attestor for testing.
Changes:
- Introduces
pkg/teeattestation/hash.gowithDomainHashfor domain-separated SHA-256 hashing - Adds
pkg/teeattestation/nitro/validate.gowithValidateAttestationfor verifying AWS Nitro attestation documents against expected PCRs and user data - Adds
pkg/teeattestation/nitro/fake/with aFakeAttestorthat produces COSE Sign1 documents verifiable without real Nitro hardware
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/teeattestation/hash.go | Domain-separated SHA-256 hashing primitive |
| pkg/teeattestation/hash_test.go | Tests for DomainHash |
| pkg/teeattestation/nitro/validate.go | AWS Nitro attestation validation with PCR and user data checks |
| pkg/teeattestation/nitro/fake/fake.go | Fake attestor producing valid COSE Sign1 docs for testing |
| pkg/teeattestation/nitro/fake/fake_test.go | Tests for FakeAttestor |
| go.mod | Adds github.com/hf/nitrite dependency |
Comments suppressed due to low confidence (1)
pkg/teeattestation/nitro/validate.go:1
- The
cosePayloadstruct has anUnprotectedfield of typecbor.RawMessage, but it is not set when constructingouterinfake.go(line 147). CBORnil/zero-value forRawMessagemay serialize differently than the empty CBOR map ({}) that COSE Sign1 expects for the unprotected header. Ifnitrite.Verifyis strict about this, it could fail. This comment applies tofake.goline 147, referencing the struct in the same file.
// Package nitro provides AWS Nitro Enclave attestation validation.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
pkg/teeattestation/nitro/validate.go
Outdated
|
|
||
| // ValidateAttestation verifies an AWS Nitro attestation document against | ||
| // expected user data and trusted PCR measurements. | ||
| func ValidateAttestation(attestation, expectedUserData, trustedMeasurements []byte, caRootsPEM string) error { |
There was a problem hiding this comment.
Intentional. Empty string means 'use production default'. All existing callers pass empty string for production and a non-empty PEM for tests. Changing this would break the ergonomics for no practical gain.
| "pcr1": hex.EncodeToString(f.pcrs[1]), | ||
| "pcr2": hex.EncodeToString(f.pcrs[2]), | ||
| } | ||
| b, _ := json.Marshal(m) |
There was a problem hiding this comment.
Added a comment. Changing the signature would break callers for an error that can't happen (json.Marshal on map[string]string).
f9dede0 to
2c727f6
Compare
pkg/teeattestation/nitro/validate.go
Outdated
|
|
||
| // ValidateAttestation verifies an AWS Nitro attestation document against | ||
| // expected user data and trusted PCR measurements. | ||
| func ValidateAttestation(attestation, expectedUserData, trustedMeasurements []byte, caRootsPEM string) error { |
There was a problem hiding this comment.
nit: rename to ValidateNitroAttestation
There was a problem hiding this comment.
It's inside the nitro folder. That should be enough, no?
There was a problem hiding this comment.
Ah, yeah. Forgot about that.
|
Would be nice to put this behind a /privacy/ or /confidential-compute/ root package and mark that thing as being Privacy codeowners. That way we can maintain better autonomy for approvals. |
Let's add privacy as the owner of this folder. I don't want to add a privacy specific top-level package. |
sure |
|
LGTM, will ship when the linting is fixed. |
There was a problem hiding this comment.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.
| Benchmark suite | Current: af5248c | Previous: c7b8c13 | Ratio |
|---|---|---|---|
BenchmarkKeystore_Sign/nop/in-process |
758 ns/op |
356.1 ns/op |
2.13 |
This comment was automatically generated by workflow using github-action-benchmark.
eef5bc4 to
af5248c
Compare
ValidateAttestation now always uses the hardcoded AWS Nitro root cert. ValidateAttestationWithRoots is available for testing with fake enclaves that use self-signed CA roots.
af5248c to
ebe046f
Compare
| if !bytes.Equal(result.Document.PCRs[1], trustedPCRs.PCR1) { | ||
| return fmt.Errorf("PCR1 mismatch: expected %x", trustedPCRs.PCR1) | ||
| } | ||
| if !bytes.Equal(result.Document.PCRs[2], trustedPCRs.PCR2) { |
There was a problem hiding this comment.
should we check somewhere that length of result.Document.PCRs is 3 (or at least 3) ?
There was a problem hiding this comment.
And sorry, how do you know that trustedPCRs will have 3 (or at least 3)?
There was a problem hiding this comment.
sorry, can't you just write:
maps.EqualFunc(result.Document.PCRs, map[uint]HexBytes{0: trustedPCRs.PCR0, 1: trustedPCRs.PCR1, 2: trustedPCRs.PCR2},
func(v1 []byte, v2 HexBytes) bool {
return bytes.Equal(v1, v2)
},
)
to compare these maps?
There was a problem hiding this comment.
I could. But I want to keep the error of which PCR mismatched, if at all. It's quite simple, the way it is right now, and I prefer that.
|
Yikes. Fixed. |
pkg/teeattestation/go.mod
Outdated
There was a problem hiding this comment.
Does this need to be a separate module?
There was a problem hiding this comment.
(a separate module would also require a general github boilerplate like https://github.com/smartcontractkit/chainlink-common/blob/main/.github/workflows/keystore.yml)
There was a problem hiding this comment.
Not a strong reason. It has two TEE specific dependencies (nitrite and cbor/v2) - didn't want to bloat the common dependency tree.
But if you think common is already bloated enough and 2 more won't do much damage, I am happy to dump the separate module.
And I didn't know about the github boilerplate.
There was a problem hiding this comment.
Moved it to the root module now.
| // COSE Sign1 attestation documents. These documents pass nitrite.Verify's | ||
| // full validation chain (CBOR parsing, cert chain, ECDSA signature, UserData, | ||
| // PCRs) without requiring real Nitro hardware. | ||
| package fake |
There was a problem hiding this comment.
How about a more descriptive name?
| package fake | |
| package nitrofake |
|
Not a strong reason. It has two TEE specific dependencies (nitrite and
cbor/v2) - didn't want to bloat the common dependency tree.
But if you think common is already bloated enough and 2 more won't do much
damage, I am happy to dump the separate module.
…On Thu, Mar 26, 2026 at 5:27 PM Jordan Krage ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
On pkg/teeattestation/go.mod
<#1899?email_source=notifications&email_token=AABSA7XFDGASARR42GBIIHT4SVK5VA5CNFSNUABKM5UWIORPF5TWS5BNNB2WEL2QOVWGYUTFOF2WK43UKJSXM2LFO4XTIMBRGU3DGOJSG42KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2K64DSL5ZGK5TJMV3V6Y3MNFRWW#discussion_r2996191395>
:
Does this need to be a separate module?
—
Reply to this email directly, view it on GitHub
<#1899?email_source=notifications&email_token=AABSA7T6BJLSN6ICFXRL5UL4SVK5VA5CNFSNUABKM5UWIORPF5TWS5BNNB2WEL2QOVWGYUTFOF2WK43UKJSXM2LFO4XTIMBRGU3DGOJSG42KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2L24DSL5ZGK5TJMV3V63TPORUWM2LDMF2GS33OONPWG3DJMNVQ#pullrequestreview-4015639274>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABSA7RK6SQC2NAG5SFSKYD4SVK5VAVCNFSM6AAAAACWTUVZDOVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHM2DAMJVGYZTSMRXGQ>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
|
Done. |
|
✅ API Diff Results -
|
Summary
pkg/teeattestation/with platform-agnostic domain-separated hashing (DomainHash)pkg/teeattestation/nitro/with AWS Nitro attestation validation (ValidateAttestation, PCR types, default CA roots)pkg/teeattestation/nitro/fake/withFakeAttestorfor testing without Nitro hardwaregithub.com/hf/nitrite(Nitro attestation verifier)Nitro-specific code is isolated in
nitro/so GCP Confidential Computing etc. can be added as sibling packages later.Used by both
confidential-compute(enclave-side) andchainlink(relay DON handler) for attestation validation and domain-separated hashing. It is an almost direct copy from https://github.com/smartcontractkit/confidential-compute/tree/main/enclave-client/attestation-validator