Skip to content

Commit b3535f6

Browse files
mswilkisonclaude
andcommitted
[DRAFT - decision-gated] feat(tbtc/signer): mirror TEE hardening stack 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>
1 parent 551bd42 commit b3535f6

19 files changed

Lines changed: 7454 additions & 19 deletions

pkg/tbtc/signer/README.md

Lines changed: 203 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# tbtc-signer (bootstrap)
22

3-
This crate is the first implementation slice of the Rust rewrite plan tracked
4-
in `../../docs/frost-migration/rust-rewrite-bootstrap.md`.
3+
This crate is the first implementation slice of the Rust rewrite plan in
4+
`../tbtc-rust-rewrite-consensus-plan.md`.
55

66
## Current scope
77

@@ -33,10 +33,7 @@ in `../../docs/frost-migration/rust-rewrite-bootstrap.md`.
3333
- Uses deterministic JSON request/response envelopes across the FFI boundary.
3434
- Provides explicit, typed error codes for retry-safe orchestration.
3535
- Keeps bootstrap synthetic finalize behavior fail-closed by default; enable it
36-
explicitly with `TBTC_SIGNER_ALLOW_BOOTSTRAP=true` in non-production profiles
37-
only.
38-
- Rejects bootstrap dealer DKG when `TBTC_SIGNER_PROFILE=production`; production
39-
requires distributed DKG wiring before this path can be enabled.
36+
explicitly with `TBTC_SIGNER_ALLOW_BOOTSTRAP=true`.
4037

4138
## Not yet implemented
4239

@@ -106,6 +103,205 @@ Sample input schemas are provided in:
106103
- `tools/tbtc-signer/scripts/admission-override.sample.json`
107104
- `tools/tbtc-signer/scripts/admission-override-registry.sample.json`
108105

106+
## TEE Governance Registry Checker (Phase A)
107+
108+
Run the governance registry validator for TEE-required signer policy artifacts:
109+
110+
```bash
111+
cd tools/tbtc-signer
112+
cargo run --bin tee_registry_checker -- \
113+
--registry scripts/tee-governance-registry-v1.sample.json \
114+
--events scripts/tee-governance-audit-events-v1.sample.json \
115+
--now-unix 1700100000
116+
```
117+
118+
Flags:
119+
120+
- `--registry <path>` (required): path to governance registry JSON
121+
- `--events <path>` (optional): path to governance audit events JSON
122+
- `--now-unix <seconds>` (optional): override current Unix timestamp for
123+
deterministic validation (useful for CI and testing)
124+
125+
Exit codes:
126+
127+
- `0`: registry/events satisfy Phase A schema and workflow checks
128+
- `1`: policy or workflow violations were detected (see JSON reason codes)
129+
- `2`: checker input/config error
130+
131+
Output schema (exit codes 0 and 1):
132+
133+
```json
134+
{
135+
"decision": "allow | reject",
136+
"reasons": [{ "code": "reason_code", "detail": "human-readable detail" }],
137+
"validated_at_unix": 1700100000
138+
}
139+
```
140+
141+
Sample input schemas are provided in:
142+
143+
- `tools/tbtc-signer/scripts/tee-governance-registry-v1.sample.json`
144+
- `tools/tbtc-signer/scripts/tee-governance-audit-events-v1.sample.json`
145+
146+
## TEE Admission Token Checker (Phase B)
147+
148+
Run the verifier/token checker for threshold-signed admission tokens:
149+
150+
```bash
151+
cd tools/tbtc-signer
152+
cargo run --bin tee_token_checker -- \
153+
--registry scripts/tee-governance-registry-v1.sample.json \
154+
--keyset scripts/tee-verifier-keyset-v1.sample.json \
155+
--token scripts/tee-admission-token.sample.json \
156+
--revocation-registry scripts/tee-token-revocation-registry-v1.sample.json \
157+
--now-unix 1700100000
158+
```
159+
160+
Flags:
161+
162+
- `--registry <path>` (required): governance registry JSON
163+
- `--keyset <path>` (required): verifier keyset JSON (`m-of-n` threshold config)
164+
- `--token <path>` (required): admission token artifact JSON (`payload_json` + signatures)
165+
- `--revocation-registry <path>` (required): token/key revocation registry JSON
166+
- `--now-unix <seconds>` (optional): deterministic time override for CI/testing
167+
168+
The checker requires `profile_status = mandatory` in the governance registry.
169+
170+
Exit codes:
171+
172+
- `0`: token satisfies Phase B checks
173+
- `1`: token/keyset/revocation violations detected (see JSON reason codes)
174+
- `2`: checker input/config error
175+
176+
Output schema (exit codes 0 and 1):
177+
178+
```json
179+
{
180+
"decision": "allow | reject",
181+
"reasons": [{ "code": "reason_code", "detail": "human-readable detail" }],
182+
"validated_at_unix": 1700100000
183+
}
184+
```
185+
186+
Sample input schemas are provided in:
187+
188+
- `tools/tbtc-signer/scripts/tee-verifier-keyset-v1.sample.json`
189+
- `tools/tbtc-signer/scripts/tee-admission-token.sample.json`
190+
- `tools/tbtc-signer/scripts/tee-token-revocation-registry-v1.sample.json`
191+
192+
`tee-admission-token.sample.json` and `tee-verifier-keyset-v1.sample.json` are
193+
schema-only examples and require real verifier keys/signatures to pass.
194+
195+
## TEE Runtime Enforcement Checker (Phase C)
196+
197+
Run the runtime selection/session checker for attestation-token and denylist
198+
enforcement:
199+
200+
```bash
201+
cd tools/tbtc-signer
202+
cargo run --bin tee_runtime_checker -- \
203+
--registry scripts/tee-runtime-governance-registry-v1.sample.json \
204+
--session scripts/tee-runtime-session-start-v1.sample.json \
205+
--now-unix 1700100000
206+
```
207+
208+
Flags:
209+
210+
- `--registry <path>` (required): governance registry JSON for runtime checks
211+
- `--session <path>` (required): runtime session/cohort snapshot JSON
212+
- `--now-unix <seconds>` (optional): deterministic time override for CI/testing
213+
214+
Runtime session phase values:
215+
216+
- `session_start`: strict token validity required
217+
- `mid_session`: expired tokens tolerated only within `grace_period_seconds`
218+
219+
Hard safety ceilings enforced by the checker:
220+
221+
- `grace_period_seconds <= 3600`
222+
- `attestation_max_age_seconds <= 86400`
223+
- `denylist_max_staleness_seconds` in `1..=300`
224+
- `max_single_vendor_share_percent` in `1..=60`
225+
226+
Exit codes:
227+
228+
- `0`: runtime session satisfies Phase C checks
229+
- `1`: runtime policy violations detected (see JSON reason codes)
230+
- `2`: checker input/config error
231+
232+
Output schema (exit codes 0 and 1):
233+
234+
```json
235+
{
236+
"decision": "allow | reject",
237+
"reasons": [{ "code": "reason_code", "detail": "human-readable detail" }],
238+
"validated_at_unix": 1700100000
239+
}
240+
```
241+
242+
Sample input schemas are provided in:
243+
244+
- `tools/tbtc-signer/scripts/tee-runtime-governance-registry-v1.sample.json`
245+
- `tools/tbtc-signer/scripts/tee-runtime-session-start-v1.sample.json`
246+
- `tools/tbtc-signer/scripts/tee-runtime-session-mid-session-grace-v1.sample.json`
247+
- `tools/tbtc-signer/scripts/tee-runtime-session-vendor-outage-v1.sample.json`
248+
249+
## TEE Phase D Enforcement Checker (Phase D)
250+
251+
Run the Phase D mode/waiver checker that applies canary and full-enforcement
252+
policy over a Phase C runtime decision:
253+
254+
```bash
255+
cd tools/tbtc-signer
256+
cargo run --bin tee_enforcement_checker -- \
257+
--registry scripts/tee-governance-registry-v1.sample.json \
258+
--context scripts/tee-enforcement-context-monitor-v1.sample.json \
259+
--now-unix 1700100000
260+
```
261+
262+
Flags:
263+
264+
- `--registry <path>` (required): governance registry JSON with break-glass policy
265+
- `--context <path>` (required): Phase D session context JSON
266+
- `--now-unix <seconds>` (optional): deterministic time override for CI/testing
267+
268+
Supported `enforcement_mode` values:
269+
270+
- `monitor_only`: record runtime violations without blocking
271+
- `soft_enforcement`: warnings + exclusion preference without blocking
272+
- `hard_enforcement_canary`: blocking applies to canary sessions only
273+
- `full_enforcement`: blocking applies to all sessions
274+
275+
Break-glass enforcement controls:
276+
277+
- scope coverage for selected operators
278+
- required quorum (`break_glass_quorum_bps`)
279+
- waiver TTL bounded by policy (`break_glass_ttl_seconds`) and hard maximum (7 days)
280+
- activation cap per 7 days (`break_glass_max_activations_per_7d`) for new activations
281+
- minimum cooldown (`break_glass_cooldown_seconds`) for new activations
282+
283+
Exit codes:
284+
285+
- `0`: `allow` or `allow_with_warnings`
286+
- `1`: `reject`
287+
- `2`: checker input/config error
288+
289+
Output schema (exit codes 0 and 1):
290+
291+
```json
292+
{
293+
"decision": "allow | allow_with_warnings | reject",
294+
"reasons": [{ "code": "reason_code", "detail": "human-readable detail" }],
295+
"validated_at_unix": 1700100000
296+
}
297+
```
298+
299+
Sample input schemas are provided in:
300+
301+
- `tools/tbtc-signer/scripts/tee-enforcement-context-monitor-v1.sample.json`
302+
- `tools/tbtc-signer/scripts/tee-enforcement-context-hard-canary-v1.sample.json`
303+
- `tools/tbtc-signer/scripts/tee-enforcement-context-full-break-glass-v1.sample.json`
304+
109305
## Encrypted State Key Providers
110306

111307
Signer state persistence is encrypted at rest. Key-provider behavior is controlled
@@ -120,19 +316,8 @@ by the following environment variables:
120316
- shell command executed via `/bin/sh -lc` when provider is `command`.
121317
- `TBTC_SIGNER_STATE_KEY_COMMAND_TIMEOUT_SECS`:
122318
- timeout for command-provider execution in seconds (default `30`, range `1..300`).
123-
- `TBTC_SIGNER_STATE_PATH`:
124-
- signer state file path. Required when `TBTC_SIGNER_PROFILE=production`;
125-
non-production profiles default to a temp-dir state file if omitted.
126319
- `TBTC_SIGNER_PROFILE`:
127-
- when set to `production`, provider `env` is rejected fail-closed,
128-
`TBTC_SIGNER_STATE_PATH` is required, bootstrap dealer DKG is rejected, and
129-
`TBTC_SIGNER_ALLOW_BOOTSTRAP` cannot enable synthetic finalize payloads.
130-
The production profile also forces ROAST strict attempt-context enforcement
131-
even if `TBTC_SIGNER_ENABLE_ROAST_STRICT` is unset or false.
132-
133-
Set these environment variables before the first FFI call in the process. The
134-
engine state handle is initialized once per process from the settled
135-
`TBTC_SIGNER_STATE_PATH` and key-provider configuration.
320+
- when set to `production`, provider `env` is rejected fail-closed.
136321

137322
Command-provider contract (`TBTC_SIGNER_STATE_KEY_COMMAND`):
138323

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# TEE Hardening Activation Gate Record
2+
3+
Date: `TBD`
4+
Status: `PENDING`
5+
Owner: `Threshold Labs + DAO Governance`
6+
Related plan:
7+
`docs/frost-migration/tee-whitelisted-signer-enforcement-plan.md`
8+
9+
## 1. Gate Statement
10+
11+
This record approves (or rejects) transitioning the TEE hardening profile
12+
status from `draft` to `mandatory`.
13+
14+
## 2. Governance Decision Metadata
15+
16+
- Governance proposal/decision ID: `TBD`
17+
- Effective timestamp (UTC): `TBD`
18+
- Quorum denominator: `TBD`
19+
- Achieved quorum: `TBD`
20+
- Required quorum: `>= 67.00%` (`activation_gate_required_quorum_bps=6700`)
21+
22+
## 3. Preconditions
23+
24+
- [ ] Validation scenarios in Section 11 of the TEE plan are complete.
25+
- [ ] No unresolved CRITICAL/HIGH findings remain in attestation path.
26+
- [ ] Incident runbook simulation is complete.
27+
- [ ] Policy and measurements are approved by DAO governance process.
28+
29+
## 3.1 Readiness Review Summary
30+
31+
The integrated TEE readiness stack completed a final merge-readiness review on
32+
2026-03-03 with recommendation `READY` for the scaffold branch. The review
33+
recorded:
34+
35+
- all eight prior Phase D enforcement-mode blockers resolved,
36+
- no remaining merge blockers,
37+
- Phase D unit coverage passing (`24/24`),
38+
- Phase A/B/C regression suites passing (`29/29`, `24/24`, `23/23`),
39+
- sample enforcement commands runnable for monitor, hard-canary, and
40+
full-enforcement break-glass contexts.
41+
42+
Remaining review notes are non-blocking future hardening items for production
43+
activation, including additional break-glass edge-case tests, structural input
44+
validation cases, and stricter duplicate-history semantics. These do not replace
45+
the governance preconditions above.
46+
47+
## 4. Approval Record
48+
49+
| Reviewer | Role | Decision | Date (UTC) | Notes |
50+
| --- | --- | --- | --- | --- |
51+
| `UNASSIGNED` | security owner | `PENDING` | `TBD` | |
52+
| `UNASSIGNED` | signer/runtime owner | `PENDING` | `TBD` | |
53+
| `UNASSIGNED` | governance delegate | `PENDING` | `TBD` | |
54+
55+
## 5. Transition Decision
56+
57+
- `profile_status_transition`: `draft -> mandatory` / `REJECTED`
58+
- Scope: `TBD`
59+
- Activation start (UTC): `TBD`
60+
61+
## 6. Rollback Controls
62+
63+
- Rollback authority: `TBD`
64+
- Rollback trigger conditions: `TBD`
65+
- Rollback execution SLA: `TBD`

pkg/tbtc/signer/docs/tee-whitelisted-signer-enforcement-plan.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ Each signer admission record should include:
7272
| `break_glass_max_activations_per_7d` | `2` | prevent break-glass chaining abuse |
7373
| `break_glass_cooldown_seconds` | `86400` | 24-hour cooldown between activations |
7474
| `break_glass_scope` | `named_operator_ids_only` | no global suspension in default policy |
75-
| `break_glass_quorum_bps` | `6700` | supermajority quorum for activation |
75+
| `break_glass_quorum_bps` | `6700` | supermajority quorum for emergency break-glass actions |
76+
| `activation_gate_required_quorum_bps` | `6700` | independent quorum threshold for `draft -> mandatory` activation gate; hard floor of 6700 bps enforced by checker |
7677
| `re_attestation_poll_interval_seconds` | `300` | signer refresh cadence |
7778

7879
Values should be tuned with canary data and incident drills.
@@ -239,6 +240,56 @@ Requirements:
239240
4. full enforcement after gate pass
240241
5. enforce break-glass abuse controls (activation caps + cooldown + scope)
241242

243+
### 10.2 Phase A Scaffold Artifacts
244+
245+
Initial Phase A schema/workflow checks are implemented in:
246+
247+
1. `tools/tbtc-signer/src/bin/tee_registry_checker.rs`
248+
2. `tools/tbtc-signer/scripts/tee-governance-registry-v1.sample.json`
249+
3. `tools/tbtc-signer/scripts/tee-governance-audit-events-v1.sample.json`
250+
251+
### 10.3 Phase B Scaffold Artifacts
252+
253+
Initial Phase B verifier/token checks are implemented in:
254+
255+
1. `tools/tbtc-signer/src/bin/tee_token_checker.rs`
256+
2. `tools/tbtc-signer/scripts/tee-verifier-keyset-v1.sample.json`
257+
3. `tools/tbtc-signer/scripts/tee-admission-token.sample.json`
258+
4. `tools/tbtc-signer/scripts/tee-token-revocation-registry-v1.sample.json`
259+
260+
### 10.4 Phase C Scaffold Artifacts
261+
262+
Initial Phase C runtime selection/session checks are implemented in:
263+
264+
1. `tools/tbtc-signer/src/bin/tee_runtime_checker.rs`
265+
2. `tools/tbtc-signer/scripts/tee-runtime-governance-registry-v1.sample.json`
266+
3. `tools/tbtc-signer/scripts/tee-runtime-session-start-v1.sample.json`
267+
4. `tools/tbtc-signer/scripts/tee-runtime-session-mid-session-grace-v1.sample.json`
268+
5. `tools/tbtc-signer/scripts/tee-runtime-session-vendor-outage-v1.sample.json`
269+
270+
### 10.5 Phase D Scaffold Artifacts
271+
272+
Initial Phase D canary/hard-enforcement checks are implemented in:
273+
274+
1. `tools/tbtc-signer/src/bin/tee_enforcement_checker.rs`
275+
2. `tools/tbtc-signer/scripts/tee-enforcement-context-monitor-v1.sample.json`
276+
3. `tools/tbtc-signer/scripts/tee-enforcement-context-hard-canary-v1.sample.json`
277+
4. `tools/tbtc-signer/scripts/tee-enforcement-context-full-break-glass-v1.sample.json`
278+
279+
Phase D final readiness outcome:
280+
281+
- final review recommendation: `READY` for the scaffold branch,
282+
- prior Phase D enforcement-mode blockers resolved: `8/8`,
283+
- merge blockers remaining: `0`,
284+
- Phase D unit tests passing: `24/24`,
285+
- Phase A/B/C regression tests passing: `29/29`, `24/24`, `23/23`,
286+
- sample enforcement commands verified for monitor-only, hard-canary, and
287+
full-enforcement break-glass contexts.
288+
289+
Non-blocking future hardening items remain for additional break-glass edge
290+
cases, structural input validation, duplicate-history behavior, and
291+
`serde(deny_unknown_fields)` policy consistency.
292+
242293
### 10.1 Mapping To ROAST Phase 5 Stages
243294

244295
1. ROAST Stage 1 (5% canary) requires TEE Phase C completed and TEE Phase D in
@@ -273,6 +324,8 @@ Before hard enforcement in production:
273324
4. policy and measurements approved by DAO governance process
274325
5. activation gate approved in governance record:
275326
- profile status transitions from `draft` to `mandatory`
327+
- approval artifact:
328+
`docs/frost-migration/tee-whitelisted-signer-activation-gate-record.md`
276329

277330
### 12.1 Activation Gate Record Requirements
278331

@@ -295,6 +348,7 @@ This plan is linked from:
295348

296349
1. `docs/frost-migration/roast-phase-5-security-rollout-gates.md`
297350
2. `docs/frost-migration/roast-phase-5-rollout-runbook.md`
351+
3. `docs/frost-migration/roast-phase-5-human-signoff-packet.md`
298352

299353
as a future mandatory TEE hardening profile for permissioned operator deployments
300354
once Section 12 activation gate is approved.

0 commit comments

Comments
 (0)