Weights · Actions · Evidence · Runnable demos

Run a policy check.
Inspect the result.

Small programs you run on your own laptop to watch the AgenTrust tools work: a tampered model file refused before it loads, an agent's action blocked by a written rule, a signed receipt checked with no network. Ten demos, about thirteen minutes in all. Four protect model files, five check what an agent does with its tools, and one checks what an agent sends to an AI model.

Software mode · CMCP_DEV_MODE=1 · no special hardware
Quick start

Start with one demo

You need Python 3.11 or later, Git, and Bash on macOS, Linux, or Windows with WSL. No cloud account and no special hardware. The demos stand in software for the chip's signed report (attestation), so they show the checks working but not the hardware protection itself.

Terminal
git clone https://github.com/agentrust-io/integrations && cd integrations/demos
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
python demo.py 1          # start with tool-call policy enforcement

The requirements install cMCP for demos 1 to 5, Weight Custody Manifest for demos 6 to 9, and a model API client for demo 10. demo.py sets dev mode and the bearer token for you, so there is nothing to export. Source: github.com/agentrust-io/integrations/tree/main/demos.

What to look for: demo 1 sends an agent's actions through a local checkpoint (the cMCP gateway) and ends with a signed record of what was allowed and refused. Because there is no real hardware, that record does not pass a hardware check. To explore weight custody, run python demo.py 6; to run the full set without pauses, use python demo.py --no-pause.

Individual commands below: run them from the demos folder with the environment activated. For demos that start cMCP, set export CMCP_BEARER_TOKEN=demo-token first. The demo.py launcher handles this setup for you.

What demo 6 prints on weight-custody-manifest 0.28.2

python demo-06-weight-custody/run.py
Weight Custody Manifest: possession is not provenance.
Real WCM code with a software (mock) attestation provider, no hardware.
1. The builder signs a manifest binding the exact weight hash
weights_hash bound : sha256:99b3e4e724d0aa75528b5b2214…
manifest signature : True (jointly signed builder + custodian)
2. Attestation gate: the key releases only into the certified stack
gate released key  : True
3. A tampered checkpoint fails before it ever loads
certified hash     : sha256:99b3e4e724d0aa75528b5b2214…
downloaded hash    : sha256:b3a36b547da3babd1dc9f2b900…
matches manifest   : False -> REFUSE to load
no human reads 2.8T parameters; the hash does the reading.
4. The fine-tune is the real IP: lineage back to the signed base
lineage verified   : True  depth 1  root is a base: True
What this is, and is not
custody active     : key held under a 1h cadence, wiped on lapse (time_floor sound)
honest scope       : accountability-grade against an operator who physically
                      owns the silicon (see TEE.fail), not silicon-proof
                      custody. It IS the provenance the download never gave you.

Shortened for width: hashes are truncated, and the section rules, the gate's enforced: note and the derivative hash are left out. The run prints them all. Every demo ends with a scope statement like that last one.

Model weights

Securing model weights

A model's weights are the trained file that is the model. A version you trained further on your own data (a fine-tune) is valuable work that exists nowhere else. These four demos protect that file: record exactly which file it is, hand the key that decrypts it only to a server that proves what it is running, and keep a checkable family tree from every derived model back to its original.

The honest limit, stated up front. If an attacker physically owns the machine, no confidential-computing chip on sale today can keep the weights safe. Published attacks such as TEE.fail and BadRAM show why. What these demos give you is a clear, signed record of who could release the key and when, which holds as long as you trust the operator not to attack their own hardware. Demo 9 adds a scheme where several parties must agree before a key is released, for when one operator's word is not enough. Anyone selling you weight protection "without operator trust assumptions" is overstating what the hardware does.

Demo 6 Weight custody ~60 seconds

What you will see: a model file with one changed byte is refused before it loads, while the genuine file gets its key.

A Weight Custody Manifest binds the checkpoint's exact weights_hash, gates the decryption key behind attestation, and carries the fine-tune's lineage.

  • a manifest jointly signed by builder and custodian binds the exact weights_hash, and the signature verifies
  • the attestation gate releases the key only for the certified serving stack: genuine nonce, approved platform, signed image measurement
  • a tampered checkpoint's hash does not match, so it is refused before it ever loads
  • a fine-tune verifies as a derivative back to the signed base
python demo-06-weight-custody/run.py
Demo 7 Closed-weight custody ~60 seconds

What you will see: a server that could leak the secret model file asks for the key and is turned away.

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.

  • a manifest with base_confidentiality: confidential, jointly signed by lab and customer
  • the key releases only into the attested, lab-signed serving stack
  • an unapproved stack, one that could export plaintext weights, is refused the key
  • same protocol as demo 6, different job
python demo-07-closed-weight/run.py
Demo 8 Derivative lineage ~60 seconds

What you will see: a model trained from a protected base is traced back to it, and an unauthorised copy of the new model is rejected.

Fine-tune inside the enclave on private data and the result is novel IP. It gets its own signed manifest with a derived_from pointer and a rights_holder split.

  • a base permitting fine-tune-only, and a derivative permitting none
  • verify_lineage resolves the derivative back to the base: chain, depth, root
  • the rights_holder records the base and derivative IP split
  • rights are monotone, so a fork of the no-derivatives derivative is rejected
python demo-08-derivative-lineage/run.py
Demo 9 Sovereign threshold ~90 seconds

What you will see: one party alone cannot decrypt the model; it takes two of the three key holders.

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.

  • the model key is split 2-of-3 across the lab, the sovereign authority, and the customer
  • a single share reconstructs nothing, so one forged attestation sits below threshold
  • two independent shareholders each attest and release their share
  • forging now means forging attestation to a quorum of independent roots, not one
python demo-09-sovereign-threshold/run.py
Agent actions

Checking what an agent does

These six put written rules at the point an agent has to pass through: five where it uses a tool, and demo 10 where it sends a request to an AI model. The rules decide what the agent may do, in which job, and with what kind of data. They are written in Cedar, an open policy language, checked on every call, and each session ends with a signed TRACE receipt of what happened.

Demo 1 cMCP in action ~90 seconds

What you will see: an agent writes and reads a file, is refused when it tries to list a folder, and gets a signed record of all three.

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.

  • write_file and read_file allowed, real files written to workspace/
  • list_dir denied by policy: HTTP 403, POLICY_DENY
  • the claim carries runtime.platform, runtime.measurement, policy.bundle_hash
  • on real Intel TDX the bundle hash flows into RTMR[2] at startup
python demo-01-cmcp-in-action/run.py
Demo 2 Policy swap is an attestation failure ~90 seconds

What you will see: someone quietly swaps the rule set, and the receipt check catches it.

The operator quietly loads a different policy bundle. The claim's hash changes, and a verifier pinned to the old hash rejects it.

  • v1 and v2 bundle hashes printed, visibly different
  • write_file now denied under v2
  • verifying a v2 claim against the pinned v1 hash fails with POLICY_HASH_MISMATCH
  • on real TDX the measurement itself changes, not just a field
python demo-02-policy-swap/run.py
Demo 3 Offline TRACE verification ~60 seconds

What you will see: a receipt checked on your machine with no network, with a plain list of what could and could not be confirmed.

Verify the signed claim with no gateway, no server, and no network call at all.

  • schema, signature, policy hash, catalog hash and audit chain all check out
  • hardware_attestation stays in unverified_fields in software mode, so the status reads partially_verified
  • on real TDX that field verifies too and the status becomes verified
  • no connection is made to anything
python demo-03-offline-trace/run.py
Demo 4 Context-aware enforcement ~90 seconds

What you will see: the same action allowed in one job and refused in another.

The same tool, the same arguments, allowed in one workflow and denied in another. The decision depends on the job the call says it belongs to. The tool's name and the model's stated reason do not change it.

  • write_file under workflow_id="invoice-run": allowed
  • the identical call under workflow_id="chat-freeform": denied, default-deny holds
  • read_file still allowed in both, so only the write capability is scoped
  • both the allow and the deny land in the signed audit chain
python demo-04-context-enforcement/run.py
Demo 5 Attribute-based enforcement ~90 seconds

What you will see: a tool that is not cleared for patient data is refused, whatever its name.

Refuse a tool based on its labels instead of its name. A tool not covered by a business associate agreement (BAA, the US contract required to handle patient data) is refused by one rule, whatever it is called.

  • tools tagged compliance_domain=clinical, baa_covered=true: allowed
  • a tool tagged baa_covered=false: denied
  • the deny comes from forbid ... when { context.baa_covered == false }, overriding the baseline permit
  • one rule covers every non-covered tool in the catalog, present and future
python demo-05-compliance-domain/run.py
Demo 10 Governed model calls ~90 seconds

What you will see: each prompt sent to a different model route, or cleaned first, depending on how sensitive its data is.

Put rules in front of a model endpoint that uses the common chat-completions API, and send each request where its kind of data is allowed to go.

  • public prompts can use the shared model route
  • personal data (PII) leaves only after names and other identifiers are stripped
  • confidential prompts and patient health data (PHI) stay on approved servers in the right region
  • the same governance boundary applies to model calls, not only MCP tools
python demo-10-model-gateway/run.py
Keep going

Where to go next