You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Design doc #3376 (docs/design/attestation-verifier-contract.md, §Governance and upgrades) — and the implementation in #3626 — bound trust in attestations wrongly accepted by a buggy verifier by permanently lowering DEFAULT_EXPIRATION_DURATION_SECONDS from 7 days to 1 day (crates/mpc-attestation/src/attestation.rs:28). After a verifier rotation, a wrongly-accepted entry then ages out within ~1 day instead of 7.
The problem: a permanent 1-day expiry is a liveness risk. Attestation freshness depends on Intel's PCCS/PCS collateral being reachable at resubmit time. A global PCCS outage (Intel's servers down) lasting ≥ 1 day could expire every node's attestation roughly simultaneously and knock out the whole MPC cluster. The 7-day window exists precisely to give operators/nodes slack across transient connectivity issues, races, and upstream outages; 1 day is too tight to be the steady-state default.
The 1-day containment window is only needed right after a verifier rotation — the moment we stop trusting entries the old (possibly buggy) verifier produced. Outside that window, the extra availability margin of 7 days is worth keeping.
User Story
As an MPC node operator, I need attestations to stay valid long enough to survive a transient global PCCS/collateral outage, so that my node (and the cluster) is not evicted during an Intel-side incident — while still allowing the protocol to quickly age out attestations produced by a verifier we've just rotated away from.
Acceptance Criteria
Change the design and implementation so that:
DEFAULT_EXPIRATION_DURATION_SECONDS is restored to 7 days — the default expiry stamped on every newly submitted attestation, including under the new verifier contract.
On each verifier rotation (a vote_tee_verifier_change that crosses threshold and updates tee_verifier_account_id), the contract shortens the expiry of all currently stored attestations to 1 day from that point — i.e. cap each stored entry's expiry_timestamp_seconds at min(existing, now + 1 day) (never extend).
Attestations submitted after the rotation are stamped with the normal 7-day expiry again (nodes resubmit hourly, so honest nodes refresh well within the shortened window).
The design doc §Governance and upgrades is updated to describe this rotation-triggered shortening instead of the permanent 1-day constant, including the PCCS-outage rationale, and the "no sweep / no per-entry bookkeeping" claim is corrected (see note below).
The original intent (per the thread) was always to shorten expiry to 1 day only on a verifier code/contract change, not permanently — this issue realigns design + code with that intent.
Implementation note / design tension: the current design explicitly avoids per-entry bookkeeping ("A wrongly-accepted entry then rides out for at most ~1 day after the rotation ... uniformly and with no sweep, flag, or per-entry bookkeeping"). Capping stored entries' expiry on rotation reintroduces a bounded per-entry update over stored_attestations, executed once when the rotation vote crosses threshold (natural home: the same threshold-crossing path in vote_tee_verifier_change). This trade-off — a one-shot rewrite on the rare rotation event in exchange for a safe 7-day steady-state window — should be captured in the doc.
Relevant code: crates/mpc-attestation/src/attestation.rs (DEFAULT_EXPIRATION_DURATION_SECONDS, AcceptedAttestation::dstack, VerifiedAttestation::re_verify), and the verifier-vote path in crates/contract/src/lib.rs / crates/contract/src/tee/tee_state.rs.
Background
Design doc #3376 (
docs/design/attestation-verifier-contract.md, §Governance and upgrades) — and the implementation in #3626 — bound trust in attestations wrongly accepted by a buggy verifier by permanently loweringDEFAULT_EXPIRATION_DURATION_SECONDSfrom 7 days to 1 day (crates/mpc-attestation/src/attestation.rs:28). After a verifier rotation, a wrongly-accepted entry then ages out within ~1 day instead of 7.The problem: a permanent 1-day expiry is a liveness risk. Attestation freshness depends on Intel's PCCS/PCS collateral being reachable at resubmit time. A global PCCS outage (Intel's servers down) lasting ≥ 1 day could expire every node's attestation roughly simultaneously and knock out the whole MPC cluster. The 7-day window exists precisely to give operators/nodes slack across transient connectivity issues, races, and upstream outages; 1 day is too tight to be the steady-state default.
The 1-day containment window is only needed right after a verifier rotation — the moment we stop trusting entries the old (possibly buggy) verifier produced. Outside that window, the extra availability margin of 7 days is worth keeping.
User Story
As an MPC node operator, I need attestations to stay valid long enough to survive a transient global PCCS/collateral outage, so that my node (and the cluster) is not evicted during an Intel-side incident — while still allowing the protocol to quickly age out attestations produced by a verifier we've just rotated away from.
Acceptance Criteria
Change the design and implementation so that:
DEFAULT_EXPIRATION_DURATION_SECONDSis restored to 7 days — the default expiry stamped on every newly submitted attestation, including under the new verifier contract.vote_tee_verifier_changethat crosses threshold and updatestee_verifier_account_id), the contract shortens the expiry of all currently stored attestations to 1 day from that point — i.e. cap each stored entry'sexpiry_timestamp_secondsatmin(existing, now + 1 day)(never extend).stored_expiry − DEFAULT_EXPIRATION_DURATION_SECONDS(crates/node/src/indexer/tx_sender.rs:269-290). This rotation-cap design makes that reconstruction invalid regardless of version skew (see note below).Resources & Additional Notes
#mpc-pull-requestson feat(contract): TEE verifier contract-account voting #3626, which changedDEFAULT_EXPIRATION_DURATION_SECONDSfrom 7d → 1d.stored_attestations, executed once when the rotation vote crosses threshold (natural home: the same threshold-crossing path invote_tee_verifier_change). This trade-off — a one-shot rewrite on the rare rotation event in exchange for a safe 7-day steady-state window — should be captured in the doc.crates/mpc-attestation/src/attestation.rs(DEFAULT_EXPIRATION_DURATION_SECONDS,AcceptedAttestation::dstack,VerifiedAttestation::re_verify), and the verifier-vote path incrates/contract/src/lib.rs/crates/contract/src/tee/tee_state.rs.stored_expiry − DEFAULT_EXPIRATION_DURATION_SECONDS(crates/node/src/indexer/tx_sender.rs:269-290), which breaks the moment node and contract disagree on the constant (version skew during rollout), producing asubmit_participant_inforetry storm. Simply reverting to 7d re-exposes the same skew during this change's rollout. Worse, the rotation-cap in this issue makes the reconstruction structurally wrong even with matching constants: after a rotation,stored_expiry = min(creation + 7d, rotation_time + 1d), so it is no longercreation + constantandexpiry − constantno longer recovers the creation time. Therefore Attestation freshness check breaks under node/contract version skew, causing a submit_participant_info retry storm #3686 must be fixed at its root (confirm via stored-vs-submitted identity or an explicit creation timestamp — see test: migration system test #1637/use expiration durations from the attestation certificate #1639) before landing the rotation-cap, not worked around. Treat Attestation freshness check breaks under node/contract version skew, causing a submit_participant_info retry storm #3686 as a blocking dependency of this issue.