One mandate. Many agents.
The human's authority as a signed, bounded, expiring object - one mandate, many agents. Every agent that acts for a person - on a phone, in a browser, in a company - should carry the same object, and every counterparty should be able to verify what it did against it. This page is that object, open.
1 · The object
A mandate is derived from the human's own words (Dutch, German, French or English), never the other way round. It is signed once and carried by any agent. The agent can never widen it. These are its fields - generated from the code that enforces them.
| field | type | default | meaning |
|---|---|---|---|
| subject | string | "user" | Whose authority this is. The agent never widens it. |
| version | integer | 1 | Mandate object version; a receipt names it. |
| per_transaction_eur | number | 400.0 | Ceiling per action. Above it: BLOCK. |
| per_month_eur | number|null | null | Ceiling per calendar month across every agent acting under this subject, together. |
| confirm_above_eur | number | 150.0 | Above it the human is asked (CONFIRM) before the action runs. |
| confirm_irreversible | boolean | true | Reversibility, not severity, decides who acts: NONE/COSTLY -> ask. |
| confirm_affects_others | boolean | true | An action that reaches another person is asked first. |
| confirm_new_counterparty | boolean | true | A merchant or address never seen before is asked first. |
| drift_tolerance_eur | number | 0.0 | How far the executed amount may differ from the shown amount (parameter binding). |
| drift_tolerance_pct | number | 0.0 | Same, as a percentage; the human's own ceiling ('small price changes up to 2%'). |
| denied_categories | string[] | ["gambling", "crypto_exchange"] | Never, whoever asks. |
| denied_capabilities | string[] | [] | Capabilities that are BLOCK, never even asked. |
| allowed_tools | string[] | [] | Empty = any KNOWN tool (see tool_policy). |
| denied_tools | string[] | [] | Tools explicitly refused. |
| tool_policy | 'default_deny'|'allow_unknown' | "default_deny" | DEFAULT-DENY: a tool the vocabulary does not know is refused. The unenumerated path never runs silently. |
| declared_tools | string[] | [] | Extra tools the tenant declared by name - now in the vocabulary. |
| protected_data | string[] | [] | DATA CLASS: leaves only to counterparties the person already dealt with. |
| sealed_data | string[] | [] | DATA CLASS: never leaves, to anyone. |
| merchants_deny | string[] | [] | Named counterparties refused. |
| retain_days | integer | 730 | How long receipts are kept. |
| export_format | string | "eu_ai_act_art14" | The oversight record format (EU AI Act Art. 12 logging / Art. 14 oversight). |
| language | string | "en" | The language the human wrote the mandate in (NL/DE/FR/EN parsed). |
| source_text | string | "" | The human's own words - the mandate is derived from them, never the other way round. |
| understood | string[] | [] | Which clauses the parser understood (provenance). |
| unparsed | string[] | [] | Which clauses it did NOT - nothing is dropped silently. |
EXAMPLE - the object behind "don't spend more than 400, always ask before anything non-refundable"
{
"allowed_tools": [],
"confirm_above_eur": 150.0,
"confirm_affects_others": true,
"confirm_irreversible": true,
"confirm_new_counterparty": true,
"declared_tools": [],
"denied_capabilities": [],
"denied_categories": [
"gambling",
"crypto_exchange"
],
"denied_tools": [],
"drift_tolerance_eur": 0.0,
"drift_tolerance_pct": 0.0,
"export_format": "eu_ai_act_art14",
"language": "en",
"merchants_deny": [],
"per_month_eur": null,
"per_transaction_eur": 400.0,
"protected_data": [],
"retain_days": 730,
"sealed_data": [],
"source_text": "don't spend more than 400, always ask before anything non-refundable",
"subject": "alice",
"tool_policy": "default_deny",
"understood": [],
"unparsed": [],
"version": 1
}2 · The receipt
Every action an agent takes under a mandate yields a receipt: what was approved is what was signed, nothing else. A receipt verifies with nothing but the receipt - no account, no network, no trust in us.
| field | meaning |
|---|---|
| mandate_hash | sha256 of the canonical mandate object the action was judged against. |
| action_hash | sha256 of the canonical parameters the human saw (parameter binding). |
| parameters | Those parameters, verbatim. |
| verdict | SILENT | NOTICE | CONFIRM | BLOCK at the signature. |
| rule_code | Which mandate rule decided - a short code the receipt carries so two receipts can be compared. |
| signer | {algorithm: 'ML-DSA-87', custody, public_key_b64} - the key that signed, and the public key to check it with. |
| ts | Unix time of the signature. |
| receipt_digest | sha3_256 of the canonical body above (without this field and the signature). |
| signature_b64 | ML-DSA-87 over 'HARNESS-OS:config:' + receipt_digest. null on a refusal (refusals carry refusal_signature_b64). |
Four lines. Anyone.
body = receipt minus {receipt_digest, signature_b64}digest = sha3_256(json.dumps(body, sort_keys=True, separators=(',',':'), ensure_ascii=True))assert digest == receipt.receipt_digestML-DSA-87.verify(public_key=body.signer.public_key_b64, message=b'HARNESS-OS:config:'+digest, signature=signature_b64)
Signature: ML-DSA-87 - NIST FIPS 204, category 5, key in hardware custody. A verifier that says "probably fine" is not a verifier: any defect is a refusal.
Online or offline
POST https://api.cryptoshieldai.ai/warrant/v1/verify with {"receipt": ...} - no key needed.
Offline: mandate_verify.py receipt.json (a NIST FIPS 204 library, e.g. quantcrypt). The reference verifier ships in the open SDK and is mutation-tested against the platform's own signer: every altered field is refused.
The full spec as JSON, with the signer's public key: GET https://api.cryptoshieldai.ai/warrant/v1/spec
3 · Carried to the rails
The payment rails are building their own mandates - AP2's Intent, Cart and Payment mandates among sixty companies. The human should never sign three. The WARRANT mandate is the one they sign; the rail's object is derived from it.
Derived, not retyped
GET /warrant/v1/mandate/{subject}/ap2 returns an AP2 IntentMandate - natural_language_description, merchants, requires_refundability, intent_expiry, user_cart_confirmation_required - from the human's one mandate, with the ceilings the rail has no slot for carried as namespaced extension fields. Every purchase under it still yields a WARRANT receipt.
Verify, don't trust.
A merchant, a registry, a platform or an insurer can check any receipt presented to it with the four lines above - today, with no agreement with us. If you run a rail and want the mandate carried natively, write to us.
4 · What is published, and what is not
Use it. Cite it.
The object, its fields and defaults; the receipt and the exact verification; the AP2 derivation; the reference verifier. A map everyone uses becomes the standard, and the one who drew it gets cited, not compared.
Named by what it does, not how.
- the check in the path of the action, before it runs - measured and published, never described
- the independent witness that is neither the agent's maker nor the counterparty
- the set question - what all of one person's or one company's agents can do together
- the key custody the receipts stand on
5 · Where it runs
WARRANT - PRO €59, TEAM €224, EMBED €14,999 a month. The mandate in the person's own words, the human asked only at the exceptions, the receipt on every action, the Article 12/14 export. The check runs in the path of the action at 0.28 ms p95, measured and published. The harness underneath: 114 doors across 16 planes.