Skip to content

fix(nitro): pre-warm the CertManager cert chain before registerKey - #972

Merged
piohei merged 5 commits into
mainfrom
fix/nitro-worker-self-prewarm
Aug 5, 2026
Merged

fix(nitro): pre-warm the CertManager cert chain before registerKey#972
piohei merged 5 commits into
mainfrom
fix/nitro-worker-self-prewarm

Conversation

@0xOsiris

@0xOsiris 0xOsiris commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Note

Medium Risk
Registration now submits extra L1 transactions and depends on correct cert-chain ordering and hint generation; failures affect enclave key onboarding but not unrelated runtime paths.

Overview
Fixes registerKey failing when on-chain CertManager lacks the attestation’s AWS cert chain (uncached certs cause "inverse hint underflow" during bundle re-verification with empty hints).

Adds a prewarm module that maps an attestation to an ordered list of verifyCACertWithHints / verifyClientCertWithHints calls: cache keys aligned with CertManager, P-384 signature hints per cert, and skipping the pinned root.

register_enclave_key now resolves CertManager via registry.verifier().certManager(), runs pre-warm before registerKey, skips already-cached certs, fails clearly on cached-but-expired certs, and tolerates concurrent pre-warm races from peer workers.

Refactors leaf_cert_pubkey_xy to delegate to new cert_pubkey_xy for reuse in the chain walk.

Reviewed by Cursor Bugbot for commit bebc547. Configure here.

0xOsiris and others added 4 commits August 4, 2026 11:38
`registerKey` reaches `NitroValidator.validateAttestationWithHints`, which re-walks the
attestation's certificate bundle via `verifyCachedCertBundle` passing **empty** hint
streams. That only succeeds on certificates already in the `CertManager` cache; an
uncached cert falls through to signature verification against an empty hint stream and
reverts with "inverse hint underflow" — regardless of how good `attestationSigHints` is.

AWS rotates the enclave leaf certificate roughly every three hours, so the cache goes cold
on its own and the pre-warm had to be re-run by hand inside that window. In practice it
never was: the alphanet registry has emitted zero `SignerRegistered` events, and the worker
crashlooped on this revert with a leaf cached ~19h earlier and one intermediate CA that had
expired 11 minutes before the pod started.

The worker now pre-warms its own chain. `prewarm::build_prewarm_plan` turns an attestation
into the ordered `verifyCACertWithHints` / `verifyClientCertWithHints` calls needed, and
`register_enclave_key` submits the uncached ones before `registerKey`. The CertManager
address is discovered via `registry.verifier().certManager()`, so there is no second
address to configure and drift.

Details:
- The pinned AWS root is written into the cache by the CertManager constructor, so it never
  needs a transaction — it only seeds the parent hash for the next cert in the chain.
- Cache keys mirror `CertManager._certCacheKey`: keccak over the TBSCertificate element for
  every cert, and the pinned constant for the root.
- A cert that is cached but expired cannot be re-verified (`_verifyCert` short-circuits on
  the cache and reverts "cert expired"), so that case fails with an explicit message
  pointing at the real fix rather than an opaque revert later.
- A peer replica caching the same cert between the check and the submit is treated as
  success, not an error.

Verified: 47 nitro tests pass (7 new); `cargo check` and `clippy -D warnings` clean for
x86_64-unknown-linux-gnu with `--features enclave`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@piohei
piohei merged commit 078fd79 into main Aug 5, 2026
14 checks passed
@piohei
piohei deleted the fix/nitro-worker-self-prewarm branch August 5, 2026 11:09
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.

2 participants