Skip to content

Commit a5445ab

Browse files
feat(site): surface the demos, lead with model weight custody (#15)
The site mentioned "demo" zero times across index.html, llms.txt and sitemap.xml, and never mentioned weight custody at all. Nine runnable demos and a published SDK were invisible to search engines and to AI crawlers. Adds /demos/ covering all nine, with the four weight-custody demos first because that is the topic buyers are searching. Title and description target the terms actually in circulation: securing model weights, attestation-gated key release, derivative lineage, sovereign threshold. The honest limit is a callout near the top, not a footnote: against an adversary who physically owns the silicon no current platform is custody-grade, TEE.fail and BadRAM are why, and demo 9's 2-of-3 threshold is the engineering answer. Competitors are shipping this as "without operator trust assumptions", which overstates what the hardware does. Saying so is the differentiator. Also adds a Tools card on the homepage, an llms.txt section written for retrieval, and a sitemap entry. Every demo description was checked line by line against the demos repo README rather than paraphrased, and all six outbound links verified 200. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 8389be9 commit a5445ab

4 files changed

Lines changed: 357 additions & 0 deletions

File tree

demos/index.html

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Model Weight Protection and Agent Governance Demos | AgenTrust</title>
7+
<meta name="description" content="Nine runnable demos for securing AI model weights and governing agents. Attestation-gated key release, tamper refusal before load, derivative lineage for fine-tunes, and 2-of-3 sovereign threshold custody. Run them on your laptop in ten minutes, no confidential-computing hardware required.">
8+
<link rel="canonical" href="https://agentrust-io.com/demos/">
9+
<meta name="robots" content="index, follow">
10+
11+
<!-- Open Graph -->
12+
<meta property="og:type" content="article">
13+
<meta property="og:site_name" content="AgenTrust">
14+
<meta property="og:title" content="Model Weight Protection and Agent Governance Demos">
15+
<meta property="og:description" content="Nine runnable demos: attestation-gated key release for model weights, tamper refusal before load, derivative lineage for fine-tunes, 2-of-3 sovereign threshold custody. Ten minutes on your laptop, no special hardware.">
16+
<meta property="og:url" content="https://agentrust-io.com/demos/">
17+
<meta property="og:locale" content="en_US">
18+
<meta property="og:image" content="https://agentrust-io.com/og.png">
19+
<meta property="og:image:width" content="1200">
20+
<meta property="og:image:height" content="630">
21+
<meta property="og:image:alt" content="AgenTrust: open standards for AI agent governance">
22+
23+
<!-- Twitter -->
24+
<meta name="twitter:card" content="summary_large_image">
25+
<meta name="twitter:title" content="Model Weight Protection and Agent Governance Demos">
26+
<meta name="twitter:description" content="Attestation-gated key release, tamper refusal before load, derivative lineage, 2-of-3 sovereign threshold. Nine runnable demos, ten minutes, no special hardware.">
27+
<meta name="twitter:image" content="https://agentrust-io.com/og.png">
28+
29+
<!-- Icons -->
30+
<link rel="icon" href="/favicon.ico" sizes="any">
31+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
32+
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
33+
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
34+
35+
<style>
36+
:root {
37+
--bg: #F2F4F7;
38+
--surface: #FFFFFF;
39+
--border: #D0D9E3;
40+
--navy: #15294B;
41+
--body: #2E4057;
42+
--muted: #6B7F94;
43+
--red: #B91C1C;
44+
--blue: #1B5EA0;
45+
--green: #1B7A4A;
46+
--amber: #C17817;
47+
--purple: #6D28D9;
48+
}
49+
* { box-sizing: border-box; }
50+
body {
51+
margin: 0;
52+
background: var(--bg);
53+
color: var(--body);
54+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
55+
line-height: 1.7;
56+
-webkit-font-smoothing: antialiased;
57+
}
58+
header.top {
59+
background: var(--navy);
60+
border-bottom: 3px solid var(--red);
61+
padding: 1rem 2rem;
62+
}
63+
header.top a.wordmark {
64+
color: #fff;
65+
text-decoration: none;
66+
font-weight: 700;
67+
letter-spacing: -0.01em;
68+
}
69+
header.top a.wordmark span { color: rgba(255,255,255,0.5); font-weight: 400; }
70+
71+
.hero { background: var(--navy); color: #fff; padding: 3.25rem 2rem 3rem; }
72+
.hero-inner { max-width: 900px; margin: 0 auto; }
73+
.eyebrow {
74+
font-size: 0.7rem; font-weight: 700; letter-spacing: 0.1em;
75+
text-transform: uppercase; color: rgba(255,255,255,0.55); margin: 0 0 0.6rem;
76+
}
77+
.hero h1 {
78+
font-size: 2.125rem; line-height: 1.2; letter-spacing: -0.025em;
79+
margin: 0 0 1rem; color: #fff;
80+
}
81+
.hero p { color: rgba(255,255,255,0.85); margin: 0 0 1rem; max-width: 700px; }
82+
.hero code {
83+
background: rgba(255,255,255,0.12); color: #fff;
84+
padding: 0.1em 0.35em; border-radius: 3px;
85+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.9em;
86+
}
87+
88+
main { max-width: 900px; margin: 0 auto; padding: 3rem 2rem 4rem; }
89+
.section-label {
90+
font-size: 0.7rem; font-weight: 700; letter-spacing: 0.1em;
91+
text-transform: uppercase; color: var(--muted); margin: 0 0 0.4rem;
92+
}
93+
h2 { color: var(--navy); font-size: 1.5rem; letter-spacing: -0.02em; margin: 0 0 0.75rem; }
94+
h3 { color: var(--navy); font-size: 1.0625rem; margin: 0 0 0.4rem; letter-spacing: -0.01em; }
95+
p { margin: 0 0 1rem; }
96+
a { color: var(--red); }
97+
.lead { max-width: 720px; }
98+
99+
.demo {
100+
background: var(--surface);
101+
border: 1px solid var(--border);
102+
border-radius: 8px;
103+
padding: 1.25rem 1.375rem;
104+
margin: 0 0 1rem;
105+
}
106+
.demo-head {
107+
display: flex; flex-wrap: wrap; align-items: baseline;
108+
gap: 0.5rem 0.75rem; margin-bottom: 0.5rem;
109+
}
110+
.demo-num {
111+
font-size: 0.68rem; font-weight: 700; letter-spacing: 0.06em;
112+
text-transform: uppercase; color: #fff; background: var(--navy);
113+
padding: 0.15rem 0.45rem; border-radius: 3px; white-space: nowrap;
114+
}
115+
.demo-time { font-size: 0.8rem; color: var(--muted); }
116+
.demo p { font-size: 0.9375rem; margin: 0 0 0.75rem; }
117+
.demo ul { font-size: 0.9375rem; margin: 0 0 0.875rem; padding-left: 1.25rem; }
118+
.demo li { margin-bottom: 0.3rem; }
119+
.demo pre {
120+
background: var(--navy); color: #E6EDF6; margin: 0;
121+
padding: 0.7rem 0.9rem; border-radius: 6px; overflow-x: auto;
122+
font-size: 0.85rem; line-height: 1.5;
123+
}
124+
pre { overflow-x: auto; }
125+
code {
126+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
127+
font-size: 0.9em; background: #E3E9F0; padding: 0.1em 0.35em; border-radius: 3px;
128+
}
129+
pre code { background: none; padding: 0; color: inherit; font-size: inherit; }
130+
131+
.callout {
132+
background: var(--surface); border: 1px solid var(--border);
133+
border-left: 3px solid var(--amber); border-radius: 6px;
134+
padding: 1rem 1.125rem; font-size: 0.9375rem; margin: 0 0 2rem;
135+
}
136+
.callout strong { color: var(--navy); }
137+
.quickstart {
138+
background: var(--surface); border: 1px solid var(--border);
139+
border-radius: 8px; padding: 1.25rem 1.375rem; margin: 0 0 2.5rem;
140+
}
141+
.quickstart pre { background: var(--navy); color: #E6EDF6; padding: 0.85rem 1rem; border-radius: 6px; font-size: 0.85rem; }
142+
hr.divider { border: none; border-top: 1px solid var(--border); margin: 2.5rem 0; }
143+
144+
footer {
145+
border-top: 1px solid var(--border); padding: 1.5rem 2rem;
146+
font-size: 0.875rem; color: var(--muted); text-align: center;
147+
}
148+
footer a { color: var(--body); }
149+
150+
@media (max-width: 640px) {
151+
.hero { padding: 2.25rem 1.25rem 2rem; }
152+
.hero h1 { font-size: 1.625rem; }
153+
main { padding: 2rem 1.25rem 3rem; }
154+
header.top { padding: 0.875rem 1.25rem; }
155+
}
156+
</style>
157+
</head>
158+
<body>
159+
160+
<header class="top">
161+
<a class="wordmark" href="/">agentrust<span>.io</span></a>
162+
</header>
163+
164+
<div class="hero">
165+
<div class="hero-inner">
166+
<p class="eyebrow">Runnable Demos</p>
167+
<h1>Don't take the spec on trust.<br>Run it.</h1>
168+
<p>Nine demos, about ten minutes end to end. Four cover custody of model weights: binding a checkpoint's hash, gating the decryption key behind attestation, tracking a fine-tune's lineage, and splitting the key so no single party can release it. Five cover governing what an agent does at the tool boundary.</p>
169+
<p>Everything runs in software mode with <code>CMCP_DEV_MODE=1</code>. No confidential-computing hardware, no cloud account, no signup.</p>
170+
</div>
171+
</div>
172+
173+
<main>
174+
175+
<div class="quickstart">
176+
<h3>Quick start</h3>
177+
<pre><code>pip install cmcp-runtime weight-custody-manifest
178+
git clone https://github.com/agentrust-io/demos &amp;&amp; cd demos
179+
export CMCP_BEARER_TOKEN=demo-token
180+
python demo.py # all nine, pausing before each
181+
python demo.py 6 # just demo 6</code></pre>
182+
<p style="font-size:0.875rem;color:var(--muted);margin:0.875rem 0 0;">Demos 1 to 5 are driven by <code>cmcp-runtime</code>. Demos 6 to 9 need only <code>weight-custody-manifest</code>, with no server and no gateway. Source: <a href="https://github.com/agentrust-io/demos">github.com/agentrust-io/demos</a>.</p>
183+
</div>
184+
185+
<p class="section-label">Model Weights</p>
186+
<h2>Securing model weights</h2>
187+
<p class="lead">A fine-tune trained on your own data is IP that never existed publicly, and the weights are where it lives. These four demos treat the weights as the asset: bind the exact checkpoint, release the decryption key only into a serving stack that proves what it is, and keep the lineage of every derivative verifiable back to its base.</p>
188+
189+
<div class="callout">
190+
<strong>The honest limit, stated up front.</strong> Against an adversary who physically owns the silicon, no current confidential-computing platform is custody-grade. <a href="https://tee.fail/">TEE.fail</a> and BadRAM are the reason. What these demos give you is accountability-grade custody under an operator-trust model, plus a threshold scheme (demo 9) for when one operator's word is not enough. Anyone selling you weight protection "without operator trust assumptions" is overstating what the hardware does.
191+
</div>
192+
193+
<div class="demo">
194+
<div class="demo-head"><span class="demo-num">Demo 6</span><strong>Weight custody</strong><span class="demo-time">~60 seconds</span></div>
195+
<p>A Weight Custody Manifest binds the checkpoint's exact <code>weights_hash</code>, gates the decryption key behind attestation, and carries the fine-tune's lineage.</p>
196+
<ul>
197+
<li>a manifest jointly signed by builder and custodian binds the exact <code>weights_hash</code>, and the signature verifies</li>
198+
<li>the attestation gate releases the key only for the certified serving stack: genuine nonce, approved platform, signed image measurement</li>
199+
<li>a tampered checkpoint's hash does not match, so it is <strong>refused before it ever loads</strong></li>
200+
<li>a fine-tune verifies as a derivative back to the signed base</li>
201+
</ul>
202+
<pre><code>python demo-06-weight-custody/run.py</code></pre>
203+
</div>
204+
205+
<div class="demo">
206+
<div class="demo-head"><span class="demo-num">Demo 7</span><strong>Closed-weight custody</strong><span class="demo-time">~60 seconds</span></div>
207+
<p>The mirror of demo 6. Here the base model is closed, a frontier lab shipping weights into a customer's or a sovereign's own enclave, so the weights themselves are the secret and the job is keeping the key off the operator.</p>
208+
<ul>
209+
<li>a manifest with <code>base_confidentiality: confidential</code>, jointly signed by lab and customer</li>
210+
<li>the key releases only into the attested, lab-signed serving stack</li>
211+
<li>an unapproved stack, one that could export plaintext weights, is refused the key</li>
212+
<li>same protocol as demo 6, different job</li>
213+
</ul>
214+
<pre><code>python demo-07-closed-weight/run.py</code></pre>
215+
</div>
216+
217+
<div class="demo">
218+
<div class="demo-head"><span class="demo-num">Demo 8</span><strong>Derivative lineage</strong><span class="demo-time">~60 seconds</span></div>
219+
<p>Fine-tune inside the enclave on private data and the result is novel IP. It gets its own signed manifest with a <code>derived_from</code> pointer and a <code>rights_holder</code> split.</p>
220+
<ul>
221+
<li>a base permitting <code>fine-tune-only</code>, and a derivative permitting <code>none</code></li>
222+
<li><code>verify_lineage</code> resolves the derivative back to the base: chain, depth, root</li>
223+
<li>the <code>rights_holder</code> records the base and derivative IP split</li>
224+
<li>rights are monotone, so a fork of the no-derivatives derivative is <strong>rejected</strong></li>
225+
</ul>
226+
<pre><code>python demo-08-derivative-lineage/run.py</code></pre>
227+
</div>
228+
229+
<div class="demo">
230+
<div class="demo-head"><span class="demo-num">Demo 9</span><strong>Sovereign threshold</strong><span class="demo-time">~90 seconds</span></div>
231+
<p>This is the answer to the limit in the callout above. If a hardware owner who forges one attestation could release a key, then never let one release be enough.</p>
232+
<ul>
233+
<li>the model key is split <strong>2-of-3</strong> across the lab, the sovereign authority, and the customer</li>
234+
<li>a single share reconstructs nothing, so one forged attestation sits below threshold</li>
235+
<li>two independent shareholders each attest and release their share</li>
236+
<li>forging now means forging attestation to a quorum of independent roots, not one</li>
237+
</ul>
238+
<pre><code>python demo-09-sovereign-threshold/run.py</code></pre>
239+
</div>
240+
241+
<hr class="divider">
242+
243+
<p class="section-label">Agent Governance</p>
244+
<h2>Governing what an agent does</h2>
245+
<p class="lead">Demos 6 to 9 protect the weights. These five govern the tool boundary: what the agent is allowed to call, under which workflow, with what compliance attributes, and what evidence survives afterwards. Cedar policy is enforced on every call and each session closes with a signed TRACE claim.</p>
246+
247+
<div class="demo">
248+
<div class="demo-head"><span class="demo-num">Demo 1</span><strong>cMCP in action</strong><span class="demo-time">~90 seconds</span></div>
249+
<p>An agent calls three tools through the cMCP gateway. Cedar is enforced on every call, and the session closes with a signed TRACE claim carrying the policy bundle hash.</p>
250+
<ul>
251+
<li><code>write_file</code> and <code>read_file</code> allowed, real files written to <code>workspace/</code></li>
252+
<li><code>list_dir</code> <strong>denied by policy</strong>: HTTP 403, <code>POLICY_DENY</code></li>
253+
<li>the claim carries <code>runtime.platform</code>, <code>runtime.measurement</code>, <code>policy.bundle_hash</code></li>
254+
<li>on real Intel TDX the bundle hash flows into RTMR[2] at startup</li>
255+
</ul>
256+
<pre><code>python demo-01-cmcp-in-action/run.py</code></pre>
257+
</div>
258+
259+
<div class="demo">
260+
<div class="demo-head"><span class="demo-num">Demo 2</span><strong>Policy swap is an attestation failure</strong><span class="demo-time">~90 seconds</span></div>
261+
<p>The operator quietly loads a different policy bundle. The claim's hash changes, and a verifier pinned to the old hash rejects it.</p>
262+
<ul>
263+
<li>v1 and v2 bundle hashes printed, visibly different</li>
264+
<li><code>write_file</code> now denied under v2</li>
265+
<li>verifying a v2 claim against the pinned v1 hash fails with <code>POLICY_HASH_MISMATCH</code></li>
266+
<li>on real TDX the measurement itself changes, not just a field</li>
267+
</ul>
268+
<pre><code>python demo-02-policy-swap/run.py</code></pre>
269+
</div>
270+
271+
<div class="demo">
272+
<div class="demo-head"><span class="demo-num">Demo 3</span><strong>Offline TRACE verification</strong><span class="demo-time">~60 seconds</span></div>
273+
<p>Verify the signed claim with no gateway, no server, and no network call at all.</p>
274+
<ul>
275+
<li>schema, signature, policy hash, catalog hash and audit chain all check out</li>
276+
<li><code>hardware_attestation</code> stays in <code>unverified_fields</code> in software mode, so the status reads <code>partially_verified</code></li>
277+
<li>on real TDX that field verifies too and the status becomes <code>verified</code></li>
278+
<li>no connection is made to anything</li>
279+
</ul>
280+
<pre><code>python demo-03-offline-trace/run.py</code></pre>
281+
</div>
282+
283+
<div class="demo">
284+
<div class="demo-head"><span class="demo-num">Demo 4</span><strong>Context-aware enforcement</strong><span class="demo-time">~90 seconds</span></div>
285+
<p>The same tool, the same arguments, allowed in one workflow and denied in another. Authorization tracks the declared call context, not the tool's name and not the model's stated intent.</p>
286+
<ul>
287+
<li><code>write_file</code> under <code>workflow_id="invoice-run"</code>: allowed</li>
288+
<li>the identical call under <code>workflow_id="chat-freeform"</code>: <strong>denied</strong>, default-deny holds</li>
289+
<li><code>read_file</code> still allowed in both, so only the write capability is scoped</li>
290+
<li>both the allow and the deny land in the signed audit chain</li>
291+
</ul>
292+
<pre><code>python demo-04-context-enforcement/run.py</code></pre>
293+
</div>
294+
295+
<div class="demo">
296+
<div class="demo-head"><span class="demo-num">Demo 5</span><strong>Attribute-based enforcement</strong><span class="demo-time">~90 seconds</span></div>
297+
<p>Deny on the tool's compliance attributes rather than its name. A tool that is not BAA-covered is refused by one guardrail rule, whatever it is called.</p>
298+
<ul>
299+
<li>tools tagged <code>compliance_domain=clinical</code>, <code>baa_covered=true</code>: allowed</li>
300+
<li>a tool tagged <code>baa_covered=false</code>: <strong>denied</strong></li>
301+
<li>the deny comes from <code>forbid ... when { context.baa_covered == false }</code>, overriding the baseline permit</li>
302+
<li>one rule covers every non-covered tool in the catalog, present and future</li>
303+
</ul>
304+
<pre><code>python demo-05-compliance-domain/run.py</code></pre>
305+
</div>
306+
307+
<hr class="divider">
308+
309+
<h2>Where to go next</h2>
310+
<ul>
311+
<li><a href="https://github.com/agentrust-io/demos">Demo source on GitHub</a>, including a web console and a plain JSON-RPC test server</li>
312+
<li><a href="https://pypi.org/project/weight-custody-manifest/">weight-custody-manifest on PyPI</a>, the reference SDK behind demos 6 to 9</li>
313+
<li><a href="https://github.com/agentrust-io/examples/tree/main/weight-custody-manifest">Worked WCM examples</a></li>
314+
<li><a href="https://cmcp.agentrust-io.com">cMCP</a> and <a href="https://trace.agentrust-io.com">TRACE</a> specifications</li>
315+
<li><a href="/quickstart/">The ten-minute cMCP quickstart</a> if you would rather write the policy yourself</li>
316+
</ul>
317+
318+
</main>
319+
320+
<footer>
321+
<a href="/">AgenTrust</a> &middot; <a href="/quickstart/">Quickstart</a> &middot; <a href="https://github.com/agentrust-io">GitHub</a>
322+
</footer>
323+
324+
</body>
325+
</html>

index.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,23 @@ <h1>Govern AI Agents<br>at the Hardware Boundary</h1>
840840

841841
<div class="product-grid">
842842

843+
<!-- Demos -->
844+
<a href="/demos/" class="product-card">
845+
<div class="card-accent" style="background: var(--green);"></div>
846+
<div class="card-body">
847+
<div class="card-tag" style="color: var(--green);">Runnable Demos</div>
848+
<div class="card-name">Nine Demos, Ten Minutes</div>
849+
<div class="card-desc">Run the specs on your own machine, no hardware required. Watch a policy block a data leak, verify a signed receipt offline, and see model weight custody refuse a tampered checkpoint before it loads.</div>
850+
</div>
851+
<div class="card-footer">
852+
<span class="card-url">agentrust-io.com/demos</span>
853+
<div style="display:flex;gap:0.5rem;align-items:center;">
854+
<span class="card-badge badge-oss">OSS</span>
855+
<svg class="card-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>
856+
</div>
857+
</div>
858+
</a>
859+
843860
<!-- TRACE Tests -->
844861
<a href="https://tests.agentrust-io.com" class="product-card">
845862
<div class="card-accent" style="background: var(--amber);"></div>

0 commit comments

Comments
 (0)