Skip to content

Commit c393c06

Browse files
feat(weight-custody-manifest): add the 30-second refuse-and-wipe demo (#62)
refuse_and_wipe.py is the headline reproducible moment: the weight-decryption key refuses to release into an enclave running a tampered serving stack, and wipe-on-lapse zeroizes it (gone, not suspended) the moment custody lapses. Real WCM code, software (mock) attestation, no hardware. Featured at the top of the README and added to the CI offline-demo set. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 08cd43d commit c393c06

3 files changed

Lines changed: 158 additions & 2 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ jobs:
162162
- name: Install the WCM SDK from PyPI
163163
run: python -m pip install -r requirements.txt
164164

165+
- name: Run the 30-second refuse-and-wipe demo
166+
run: python refuse_and_wipe.py
167+
165168
- name: Run the end-to-end custody demo
166169
run: python open_model_e2e.py
167170

weight-custody-manifest/README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,19 @@ cd examples/weight-custody-manifest
1818
pip install -r requirements.txt # weight-custody-manifest>=0.19.0, Python 3.11+
1919
```
2020

21-
The three offline demos need nothing else. `real_open_model.py` needs run-local extras (below).
21+
The offline demos need nothing else. `real_open_model.py` needs run-local extras (below).
22+
23+
---
24+
25+
## Start here: the 30-second demo
26+
27+
`refuse_and_wipe.py` is the whole idea in two moments: the weight-decryption key **refuses** to release into an enclave running a tampered serving stack, and **wipe-on-lapse** zeroizes it the moment custody lapses (gone, not suspended).
28+
29+
```bash
30+
python refuse_and_wipe.py
31+
```
32+
33+
The demos below go deeper on the same machinery.
2234

2335
---
2436

@@ -64,7 +76,7 @@ python real_open_model.py --local path/to/model.safetensors # skip the downloa
6476

6577
## What runs in CI
6678

67-
The three offline demos (`open_model_e2e.py`, `sovereign_self_custody.py`, `snp_replay.py`) run in CI against the published PyPI package and must exit 0. `real_open_model.py` is not in CI (it downloads a model).
79+
The offline demos (`refuse_and_wipe.py`, `open_model_e2e.py`, `sovereign_self_custody.py`, `snp_replay.py`) run in CI against the published PyPI package and must exit 0. `real_open_model.py` is not in CI (it downloads a model).
6880

6981
## Reference
7082

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
"""The 30-second demo: the key refuses to release, and wipe-on-lapse zeroizes it.
2+
3+
Two moments, real WCM code with a software (mock) attestation provider (no
4+
hardware):
5+
6+
1. REFUSE - the KBS will not release the weight-decryption key into an enclave
7+
running an unapproved serving stack. A silently modified fork gets nothing,
8+
so the weights it holds stay encrypted.
9+
2. WIPE - once released, the key lives only for the attestation cadence. Miss
10+
the re-attestation and the enclave zeroizes it. The key is gone, not
11+
suspended, which bounds worst-case exposure to a single cadence window even
12+
if every revocation signal is blocked.
13+
14+
pip install weight-custody-manifest
15+
python refuse_and_wipe.py
16+
"""
17+
from __future__ import annotations
18+
19+
import hashlib
20+
from datetime import datetime, timedelta, timezone
21+
22+
from wcm import (
23+
Ed25519Signer,
24+
EnclaveSession,
25+
KeyBrokerService,
26+
KeyWipedError,
27+
SoftwareProvider,
28+
WeightCustodyManifest,
29+
generate_ed25519,
30+
)
31+
32+
33+
def sha256(data: bytes) -> str:
34+
return "sha256:" + hashlib.sha256(data).hexdigest()
35+
36+
37+
def banner(text: str) -> None:
38+
print(f"\n{'=' * 64}\n{text}\n{'=' * 64}")
39+
40+
41+
def build_manifest(weights_hash: str, serving: str, org: str) -> dict:
42+
return {
43+
"manifest_version": "0.1",
44+
"weights_hash": weights_hash,
45+
"builder": {"identity": org, "signing_key": "ed25519:demo"},
46+
"release_terms": {
47+
"license": "Frontier-Model-License",
48+
"permitted_derivatives": "fine-tune-only",
49+
"derivatives": "fine-tune-only",
50+
"permitted_environments": ["enterprise-governed-enclave"],
51+
},
52+
"release_policy": {
53+
"required_assurance_tier": "hardware-attested",
54+
"trusted_time_source": "secure-tsc",
55+
"required_hw_platform": ["amd-sev-snp", "nvidia-cc-gpu"],
56+
"required_gpu_measurement": {"rim_pin": "nvidia-rim:golden"},
57+
"required_serving_image": {
58+
"signer": "ed25519:demo",
59+
"release_rule": "prefer-current",
60+
"accepted_measurements": [{"measurement": serving, "status": "current"}],
61+
},
62+
"attestation_revocation_check": "live-per-release, max-cache-age: short-window",
63+
"revocation_authority": "builder-and-opaque-joint",
64+
},
65+
"custody": {
66+
"custodian": org,
67+
"custodian_type": "customer-self-custody",
68+
"kbs_image": {"measurement": sha256(b"reference-kbs-image"), "signer": "ed25519:demo"},
69+
"enclave_id": "did:example:enclave-01",
70+
"attestation_cadence": "1h",
71+
},
72+
"base_confidentiality": "gated-open",
73+
"deployment_model": "builder-to-customer",
74+
}
75+
76+
77+
def main() -> None:
78+
org = "frontier-labs"
79+
builder, custodian = generate_ed25519(), generate_ed25519()
80+
81+
weights_hash = sha256(b"<the certified model weights>")
82+
approved = sha256(b"vllm-0.6.3 + policy-bundle-v2 (the builder-signed serving stack)")
83+
84+
doc = build_manifest(weights_hash, approved, org)
85+
manifest = WeightCustodyManifest.model_validate(doc)
86+
manifest = manifest.with_signatures([
87+
Ed25519Signer(builder).sign(manifest.unsigned_dict(), role="builder", signer=org),
88+
Ed25519Signer(custodian).sign(manifest.unsigned_dict(), role="custodian", signer=org),
89+
])
90+
91+
kbs = KeyBrokerService({weights_hash: b"the-weight-decryption-key"})
92+
93+
# -- Moment 1: REFUSE ------------------------------------------------------
94+
banner("1. A tampered enclave asks for the key. It gets nothing.")
95+
tampered = sha256(b"vllm-0.6.3 + a BACKDOORED policy bundle")
96+
challenge = kbs.issue_challenge()
97+
bad_evidence = SoftwareProvider().produce(
98+
challenge,
99+
serving_image_measurement=tampered, # not what the builder signed
100+
gpu_measurement="nvidia-rim:golden",
101+
)
102+
decision = kbs.verify_and_release(manifest, bad_evidence)
103+
print("serving stack : UNAPPROVED (a modified fork)")
104+
print("key released :", decision.released)
105+
print("why :", next(c.detail for c in decision.failures))
106+
print("-> the weights it holds stay encrypted. The fork cannot decrypt them.")
107+
108+
# -- The approved enclave gets the key -------------------------------------
109+
banner("2. The approved enclave attests. The key releases.")
110+
challenge = kbs.issue_challenge()
111+
good_evidence = SoftwareProvider().produce(
112+
challenge,
113+
serving_image_measurement=approved,
114+
gpu_measurement="nvidia-rim:golden",
115+
)
116+
decision = kbs.verify_and_release(manifest, good_evidence)
117+
print("serving stack : builder-signed and attested")
118+
print("key released :", decision.released)
119+
120+
# -- Moment 2: WIPE-ON-LAPSE -----------------------------------------------
121+
banner("3. Miss the re-attestation. The enclave zeroizes the key.")
122+
t0 = datetime(2026, 1, 1, tzinfo=timezone.utc)
123+
session = EnclaveSession.from_release(manifest, decision, now=lambda: t0)
124+
print("cadence :", doc["custody"]["attestation_cadence"],
125+
" time_floor:", session.time_floor.value)
126+
session.use_key(now=t0)
127+
print("served a request : key present")
128+
later = t0 + timedelta(hours=1, minutes=1) # past the 1h window, no re-attest
129+
try:
130+
session.use_key(now=later)
131+
print("served a request : key present") # not reached
132+
except KeyWipedError:
133+
print("re-attest missed : key ZEROIZED")
134+
print("state :", session.state.value, "(gone, not suspended)")
135+
print("-> worst-case exposure is one cadence window, even if revocation is blocked.")
136+
137+
banner("Refuse. Release only on proof. Wipe on lapse.")
138+
139+
140+
if __name__ == "__main__":
141+
main()

0 commit comments

Comments
 (0)