Skip to content

[DRAFT - decision-gated] feat(tbtc/signer): add TEE hardening checker stack#4007

Draft
mswilkison wants to merge 5 commits into
extraction/frost-signer-mirror-2026-05-26from
extraction/frost-signer-tee-stack-2026-05-26
Draft

[DRAFT - decision-gated] feat(tbtc/signer): add TEE hardening checker stack#4007
mswilkison wants to merge 5 commits into
extraction/frost-signer-mirror-2026-05-26from
extraction/frost-signer-tee-stack-2026-05-26

Conversation

@mswilkison
Copy link
Copy Markdown
Contributor

@mswilkison mswilkison commented May 26, 2026

⚠️ DRAFT — decision-gated

This PR adds the optional TEE signer-hardening readiness stack on top of
PR #4005, which
lands the base FROST/ROAST Rust signer at pkg/tbtc/signer/.

It must NOT be undrafted or merged until:

  1. PR feat(tbtc/signer): mirror FROST/ROAST Rust signer from tBTC monorepo #4005 merges.
  2. Threshold's policy decision on TEE enforcement for signers is explicit and documented.
  3. This branch is rebased onto canonical main after feat(tbtc/signer): mirror FROST/ROAST Rust signer from tBTC monorepo #4005 merges.

Canonical repo note

This PR was initially sourced from
tlabs-xyz/tbtc#88, but
threshold-network/keep-core is now the canonical repo for the signer. The
monorepo/source-PR reference is provenance only; follow-up fixes in this PR are
ordinary keep-core changes and are not expected to remain byte-for-byte mirrors
of the old source branch.

Scope

Four-phase TEE checker stack:

  • Phase A — governance registry + audit-event validation (tee_registry_checker)
  • Phase B — verifier/keyset/token/revocation validation (tee_token_checker)
  • Phase C — runtime token + denylist + vendor-diversity enforcement (tee_runtime_checker)
  • Phase D — enforcement modes + break-glass controls (tee_enforcement_checker)

Files

Path Count
pkg/tbtc/signer/src/bin/tee_*.rs 4 Rust binaries
pkg/tbtc/signer/scripts/tee-*.sample.json 12 sample configs
pkg/tbtc/signer/README.md 1 README update
pkg/tbtc/signer/docs/tee-whitelisted-signer-activation-gate-record.md + tee-whitelisted-signer-enforcement-plan.md 2 docs

Follow-up fixes included

  • Rebases/merges the branch onto the current feat(tbtc/signer): mirror FROST/ROAST Rust signer from tBTC monorepo #4005 signer base so the full
    signer Rust checks workflow is present.
  • Keeps the feat(tbtc/signer): mirror FROST/ROAST Rust signer from tBTC monorepo #4005 README path fixes and production-profile/state-key
    documentation, and updates the new TEE sections to use pkg/tbtc/signer/.
  • Rejects verifier keysets that reuse the same Schnorr public key under
    different key_ids, closing the threshold-quorum bypass.
  • Bounds reused break-glass incident tickets by the original history activation
    time and policy TTL, so an old ticket cannot refresh its waiver window.
  • Applies the same hard ceilings for attestation age and denylist staleness
    across the registry/token/runtime checkers.
  • Makes TEE checker clock reads fail closed if the system clock is before the
    Unix epoch.

Initial provenance

Verification

Local verification on the latest pushed head:

cargo fmt --manifest-path pkg/tbtc/signer/Cargo.toml -- --check
cargo clippy --manifest-path pkg/tbtc/signer/Cargo.toml --all-targets -- -D warnings
TBTC_SIGNER_STATE_PATH=/tmp/tbtc-signer-ci-state-pr4007-local.json \
  cargo test --manifest-path pkg/tbtc/signer/Cargo.toml

Plan context

This is an optional, decision-gated addition to the FROST extraction. Unlike the
mandatory extraction/mirror PRs, this PR's merge depends on the Threshold TEE
policy decision, not just operational readiness.

🤖 Generated with Claude Code

…k from tBTC monorepo

⚠️ DRAFT — DECISION-GATED. This PR mirrors the source PR
tlabs-xyz/tbtc#88 which is itself a decision-gated draft. It must NOT
merge until the Threshold policy decision to require TEE operation
for signers is explicit.

Stacked on top of [PR #4005](https://github.com/threshold-network/
keep-core/pull/4005) which lands the base FROST/ROAST Rust signer at
pkg/tbtc/signer/. This PR adds the optional TEE signer-hardening
checker stack on top.

Phases A-D (per source PR #88)
- Phase A: governance registry + audit-event validation
  (tee_registry_checker)
- Phase B: verifier/keyset/token/revocation validation
  (tee_token_checker)
- Phase C: runtime token + denylist + vendor-diversity enforcement
  (tee_runtime_checker)
- Phase D: enforcement modes + break-glass controls
  (tee_enforcement_checker)

Files (19 total — all mirror status)
- 4 Rust binaries at pkg/tbtc/signer/src/bin/
- 12 sample config JSON files at pkg/tbtc/signer/scripts/
- 1 README.md update at pkg/tbtc/signer/
- 2 docs at pkg/tbtc/signer/docs/ (tee-whitelisted-signer-activation-
  gate-record.md + tee-whitelisted-signer-enforcement-plan.md)

Provenance
- Source repository: tlabs-xyz/tbtc
- Source PR: #88 (decision-gated, draft)
- Source commit (PR #88 HEAD): 31f0aa2b8efbf8ac42909f8e8d4ce67248cb478e
- Source branch: feat/tee-phase-a-governance-registry (stacked on
  feat/frost-schnorr-migration)
- Base for THIS PR: extraction/frost-signer-mirror-2026-05-26 (PR #4005)
- Source PR includes stacked phases B, C, D from PRs #89, #90, #91
  merged into PR #88's branch

Decision gate
The source PR #88 description is explicit: this stays in draft until
the runtime TEE policy decision is made. The same constraint applies
to this canonical mirror — DO NOT MERGE before:
1. PR #4005 (base FROST signer) lands
2. Threshold policy decision on TEE enforcement for signers is
   explicit and documented (per the source PR's "Decision-Gated"
   framing)

Verification (per plan v38 §7.2 mirror status)
For each file:
- sha256(git show 31f0aa2b8e:<sourcePath>) ==
  sha256(file at this PR head at <targetPath>)

The 19 files port as byte-for-byte mirrors with path normalization:
- tools/tbtc-signer/* → pkg/tbtc/signer/*
- docs/frost-migration/tee-* → pkg/tbtc/signer/docs/tee-*

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b4c1d0e6-a5e8-4b62-9c56-39395c2ef990

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch extraction/frost-signer-tee-stack-2026-05-26

Comment @coderabbitai help to get the list of available commands and usage tips.

mswilkison added a commit that referenced this pull request May 26, 2026
Resolves CI failures on PR #4005 (signer mirror):

1. TLA model checks: run_tla_models.sh lacked executable bit at
   canonical HEAD. CI ran the script directly (no `bash` prefix),
   which fails with `Permission denied`. Fixed via
   `git update-index --chmod=+x`.

2. Signer formal invariants: engine.rs's
   formal_verification_roast_attempt_context_shared_vectors_match_
   expected_values test referenced vectors at a path stale from
   the umbrella's docs/frost-migration/test-vectors/ layout. The
   manifest places the vector at the canonical-signer test/vectors/
   subdir (pkg/tbtc/signer/test/vectors/roast-attempt-context-v1.json
   per the source-to-target map). Updated the
   `PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(...)` argument from
   `../../docs/frost-migration/test-vectors/roast-attempt-context-v1.json`
   (umbrella-relative) to `test/vectors/roast-attempt-context-v1.json`
   (signer-CARGO_MANIFEST_DIR-relative, where the vector actually
   lives at canonical HEAD).

Verified locally:
- ls -l shows executable bit set on run_tla_models.sh
- engine.rs path now resolves to the correct mirror location
- Vector exists at pkg/tbtc/signer/test/vectors/roast-attempt-context-v1.json

Same fix needs to be applied to PR #4007 (stacked on #4005)
in a follow-up commit on its branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mswilkison mswilkison changed the title [DRAFT - decision-gated] feat(tbtc/signer): mirror TEE hardening stack from tBTC monorepo [DRAFT - decision-gated] feat(tbtc/signer): add TEE hardening checker stack May 27, 2026
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