Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,28 @@ jobs:

- name: Run the delegation demo
run: python delegation_agent.py

weight-custody-manifest:
runs-on: ubuntu-latest
defaults:
run:
working-directory: weight-custody-manifest
steps:
- uses: actions/checkout@v7

- name: Set up Python 3.11
uses: actions/setup-python@v7
with:
python-version: "3.11"

- name: Install the WCM SDK from PyPI
run: python -m pip install -r requirements.txt

- name: Run the end-to-end custody demo
run: python open_model_e2e.py

- name: Run the sovereign threshold demo
run: python sovereign_self_custody.py

- name: Replay a SEV-SNP quote offline
run: python snp_replay.py
76 changes: 76 additions & 0 deletions weight-custody-manifest/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# weight-custody-manifest: Custody for Model Weights

The other examples in this repo govern what an agent may **do**. This one governs the model **weights** themselves: when a builder deploys a model into a customer's own or sovereign infrastructure, how do you prove the weights running in the enclave are exactly the ones the builder shipped, release the decryption key only against a valid hardware attestation, wipe it when custody lapses, and carry the lineage of every derivative?

That is the [Weight Custody Manifest](https://pypi.org/project/weight-custody-manifest/) (WCM): an open protocol and reference SDK. These four demos run its real code.

For a public open-weight model, base-weight confidentiality is theater (anyone can download the weights), so the same flow does the work that still matters: **integrity and provenance** (is this the model the builder shipped, or a tampered copy), **license as a release condition**, **derivative custody and lineage**, and a **kill switch**.

> **Honest scope.** WCM does not claim silicon-enforced custody against an operator who physically owns the hardware. Cheap published memory-bus attacks (TEE.fail, BadRAM) extract keys from live confidential-computing memory, so against that adversary WCM is accountability-grade (cost, detection, containment, mandatory physical hardening), not cryptographic custody. It is custody-grade against software and remote adversaries. The demos below use a software (mock) attestation provider so they run with no hardware; the hardware-rooted step is validated separately on real SEV-SNP and TDX silicon.

---

## Setup

```bash
git clone https://github.com/agentrust-io/examples.git
cd examples/weight-custody-manifest
pip install -r requirements.txt # weight-custody-manifest>=0.19.0, Python 3.11+
```

The three offline demos need nothing else. `real_open_model.py` needs run-local extras (below).

---

## The demos

### 1. `open_model_e2e.py` -- the whole flow, end to end

The full six-step Weight Custody Manifest flow on an open-weight model with a mock attestation provider: sign the joint manifest (builder + custodian), run the attestation-gated key release, hold the key under a wipe-on-lapse custody lease, enforce the license as a release condition, then fine-tune into a derivative and verify its lineage back to the base. Narrated, and honest about which steps are real work versus theater for a public model. Runs anywhere.

```bash
python open_model_e2e.py
```

### 2. `sovereign_self_custody.py` -- threshold release, no single point of trust

Sovereign self-custody with a 2-of-3 threshold split-key (SPEC 3.5): the release key is split with Shamir secret sharing so no single party can release the weights alone. Real WCM code, software attestation, runs anywhere.

```bash
python sovereign_self_custody.py
```

### 3. `snp_replay.py` -- replay a real attestation, offline

The CPU half of Layer 2's composite verification (SPEC 3.2), run offline against a recorded AMD SEV-SNP quote. It exercises exactly what a key broker runs before releasing a key: parse the SNP report, verify the VCEK to ASK to ARK certificate chain to a trusted AMD root, verify the report's own signature, and confirm REPORT_DATA binds the challenge nonce (anti-replay). A synthetic bundle is committed in `fixtures/` so it runs anywhere; pass a captured bundle to replay genuine silicon.

```bash
python snp_replay.py # committed synthetic bundle
python snp_replay.py path/to/snp_quote.json # a bundle captured on a real Azure SEV-SNP CVM
```

### 4. `real_open_model.py` -- run-local, over real weights

The same flow over a **real** open model's actual bytes: it downloads an open model (SmolLM2-135M by default, ~270MB), hashes its real safetensors into the manifest, includes a tamper demo (a one-byte-flipped fork no longer matches the manifest), and with `--infer` loads the model and generates so the certified serving stack is a real running model. Network and heavy, so it is run-local and excluded from CI.

```bash
pip install -r requirements-infer.txt
python real_open_model.py # download, hash, full flow, tamper demo
python real_open_model.py --infer # also load the model and generate
python real_open_model.py --local path/to/model.safetensors # skip the download
```

---

## What runs in CI

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).

## Reference

- Package: [weight-custody-manifest on PyPI](https://pypi.org/project/weight-custody-manifest/)
- `manifest.example.json` in this folder is a sample signed manifest for reference.

## License

Apache 2.0. See [LICENSE](../LICENSE) in the repo root.
11 changes: 11 additions & 0 deletions weight-custody-manifest/fixtures/snp_quote_synthetic.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"kind": "wcm-snp-quote-bundle/v1",
"source": "synthetic",
"note": "Self-consistent synthetic ARK->VCEK chain and report. NOT real hardware. Replace with tools/capture_snp_quote.py output for a genuine Azure SEV-SNP quote.",
"report_b64": "AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACaLbLiPxUEzQVmBlU6wEnF5xjo+c6SM4dt8aehghr4hQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOVfr/UlF6aVEeNEtcgt1yVfTcnaevR3bh8NkO8NBC9ugKwnqgg4seL0yJuRGoDOMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAugtnFRQ0+9Ir8kMPO+NbzMBsl+B3RvfrmVwsW4klzwgY61mK2LM16sbWbMWhqExDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"vcek_pem": "-----BEGIN CERTIFICATE-----\nMIIBkjCCARigAwIBAgIUB28IzgyENEygWjv7jqffhGZpw7swCgYIKoZIzj0EAwMw\nNDEyMDAGA1UEAwwpc3ludGhldGljLXNucC1yb290IChzdGFuZC1pbiBmb3IgQU1E\nIEFSSykwIBcNMjAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMB8xHTAbBgNV\nBAMMFFNFVi1WQ0VLIChzeW50aGV0aWMpMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE\nfNprLZF3rSMcTK0kLOZfBlfX7+KVQEbq9kmJOjKxDF2T1bKC0kF0jeFT6aq574wx\nTiIqGq7MMPWAdSQKHcQ6s8mcQZBZtODpJwDF683MnNc7hnHqN/AdLq8v77WTc5gp\nMAoGCCqGSM49BAMDA2gAMGUCMQDrVxfCf2knshEQvL+vyUuTU/nk/+QHpWDP+WAk\naMNdRUrzh3SGlZIAwgtqq+seorgCMF0X9n1VutxigXAXaWkHje6BpuAoyKFWYdmN\n1gePcPp9kUJZ/nSu9RIl7NvwMueinw==\n-----END CERTIFICATE-----\n",
"intermediates_pem": [],
"root_pem": "-----BEGIN CERTIFICATE-----\nMIIBvTCCAUKgAwIBAgIUIB3+SQg0A8tekhc1NbDQ9LSCE8IwCgYIKoZIzj0EAwMw\nNDEyMDAGA1UEAwwpc3ludGhldGljLXNucC1yb290IChzdGFuZC1pbiBmb3IgQU1E\nIEFSSykwIBcNMjAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMDQxMjAwBgNV\nBAMMKXN5bnRoZXRpYy1zbnAtcm9vdCAoc3RhbmQtaW4gZm9yIEFNRCBBUkspMHYw\nEAYHKoZIzj0CAQYFK4EEACIDYgAEuUSltY1Uj1sQzYTsecVdrNq9x0sgogawXEOl\nG/hcShU4GgPfFxUhryvWyeujHsaaz05LXPXVf/wJujBIrSxrAfxHdkTlfjuLzP5P\nEimoco+iYXuBjgo+Sz7nJaL36ZBaoxMwETAPBgNVHRMBAf8EBTADAQH/MAoGCCqG\nSM49BAMDA2kAMGYCMQDmJrgizN8uN1kQbxV8qW+1yac3XBpoDxwzMVYWD/U+yHbY\npAdF3OgGvlH5MWxTcM0CMQC4spaNY5CzLmMctCIyHz8Js9wbDpfGTAdbYB1rTwUr\ndF/mAzWU2hWC53hx5/T8oxw=\n-----END CERTIFICATE-----\n",
"expected_nonce": "abababababababababababababababababababababababababababababababab",
"expected_measurement": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
}
71 changes: 71 additions & 0 deletions weight-custody-manifest/manifest.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"manifest_version": "0.1",
"weights_hash": "sha256:4a1c9b024a1c9b024a1c9b024a1c9b024a1c9b024a1c9b024a1c9b024a1c9b02",
"builder": {
"identity": "example-builder",
"signing_key": "ed25519:builder-key-placeholder"
},
"release_terms": {
"license": "customer-deployment-agreement-ref:CDA-2026-0091",
"permitted_derivatives": "fine-tune-only, no re-export of base weights",
"permitted_environments": ["opaque-cmcp-attested-enclave"],
"jurisdiction_restriction": "US, EU"
},
"release_policy": {
"required_assurance_tier": "hardware-attested",
"physical_hardening": "not-required",
"trusted_time_source": "secure-tsc",
"memory_fingerprint_challenge": "not-required",
"required_hw_platform": ["amd-sev-snp", "nvidia-cc-gpu"],
"required_gpu_measurement": {
"rim_pin": "nvidia-rim:driver+vbios golden measurement id",
"note": "GPU attestation report is a separate evidence chain from the CVM report; verify both plus the serving-image measurement, bound by a nonce echo (SPEC 3.2)"
},
"tenancy": "shared",
"required_serving_image": {
"signer": "ed25519:builder-key-placeholder",
"release_rule": "prefer-current: refuse a retiring image when a current one is available; require signed/attested time for retire_after, never the host clock",
"accepted_measurements": [
{
"measurement": "sha256:5e2d5e2d5e2d5e2d5e2d5e2d5e2d5e2d5e2d5e2d5e2d5e2d5e2d5e2d5e2d5e2d",
"status": "current"
},
{
"measurement": "sha256:6f3e6f3e6f3e6f3e6f3e6f3e6f3e6f3e6f3e6f3e6f3e6f3e6f3e6f3e6f3e6f3e",
"status": "retiring",
"retire_after": "2026-07-16T00:00:00Z"
},
{
"measurement": "sha256:70af70af70af70af70af70af70af70af70af70af70af70af70af70af70af70af",
"status": "revoked"
}
],
"note": "key decrypts only under a builder-signed serving stack whose measurement is current or retiring; status:revoked hard-fails immediately"
},
"key_release_mode": "attestation-gated",
"replay_protection": "kbs-nonce-required",
"attestation_revocation_check": "live-per-release, max-cache-age: short-window",
"revocation_authority": "builder-and-opaque-joint",
"sovereign_profile": {
"enabled": false,
"revocation_authority": "quorum",
"sovereign_signer": null,
"note": "when enabled, no single party (builder included) can revoke or dark the model unilaterally"
}
},
"custody": {
"custodian": "opaque-systems",
"custodian_type": "opaque-hosted",
"kbs_image": {
"measurement": "sha256:abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234",
"signer": "ed25519:opaque-key-placeholder",
"note": "the key release service runs in an attested enclave in every profile, Opaque-hosted included"
},
"enclave_id": "did:opaque:example-enclave-04",
"attestation_cadence": "24h",
"kbs_attestation_cadence": "24h"
},
"base_confidentiality": "confidential",
"deployment_model": "builder-to-customer",
"signatures": []
}
Loading