Agent Constitutions: Proving What an AI Agent Promised

Know Your Agent has two solved axes and one missing one. Identity tells you who an agent is. Reputation tells you what others think of it. Neither tells you what it has committed to do, or lets you prove it later. Here is the small, verifiable mechanism that closes the gap.

June 27, 2026 4 min read By Petteri Leinonen, Founder, AsterPay

When an autonomous agent shows up to move money, a counterparty asks three different questions. Who is this? is identity: an on-chain registry like ERC-8004, operator KYB, sanctions screening. What does the network think of it? is reputation: history, endpoint quality, third-party signals. Both are well covered. The third question is the one nobody answers: what has this agent actually committed to do, and can I verify it?

Identity is who. Reputation is what others think. A constitution is what the agent promised, in a form anyone can check.

A constitution is a hashed, committed policy

An agent constitution is a machine-readable declaration of the rules an agent operates within: spend caps, allowed payment rails, chains and tokens, counterparty mode, and a kill-switch on sanctions. It is plain data.

{
  "version": 1,
  "agent": { "wallet": "0x...", "agentId": "16850" },
  "spending": { "perTxMaxUsd": 1000, "dailyMaxUsd": 5000 },
  "rails": { "allowed": ["x402", "mpp"], "chains": ["base"], "tokens": ["USDC", "EURC"] },
  "counterparties": { "mode": "open" },
  "risk": { "killSwitchOnSanction": true },
  "issuedAt": "2026-06-27T00:00:00.000Z"
}

The agent computes a canonical SHA-256 hash of that policy and commits the hash to its own ERC-8004 identity metadata under the key constitution. The hash is the commitment. The policy stays readable; the chain holds the fingerprint.

Canonicalization is the part that matters

A hash is only useful if two parties computing it independently get the same value. JSON does not guarantee that, because key order and whitespace vary. So before hashing we canonicalize: sort object keys, drop insignificant whitespace, keep array order. {a,b} and {b,a} must produce an identical byte string and therefore an identical hash.

canonicalize(policy)  // JCS-style: keys sorted, no whitespace, arrays in order
hash = "0x" + sha256(utf8(canonical))

Now verification is a pure function. Re-canonicalize the stored policy, re-hash it, and compare to the value committed on-chain. No service trust required, no internal state: any third party with the policy and the chain can reproduce the result.

local   = sha256(canonicalize(policy))
onChain = readErc8004Metadata(agentId, "constitution")
match   = normalize(local) === normalize(onChain)
Tamper-evident by construction. If the agent quietly edits its policy, the recomputed hash no longer matches the on-chain commitment, and the mismatch is visible to anyone. A promise you can change without anyone noticing is not a promise.

We never hold the agent's key

The on-chain commit is signed by the agent with its own key. AsterPay computes the canonical hash, stores the policy so it can be served and re-hashed, and verifies the match. We are the verifier, not the signer. This is deliberate: the party that declares the policy is the party that signs the commitment, and a verification service that cannot move your funds is a smaller thing to trust.

What this does, and what it does not

Be precise about the boundary. A constitution proves an agent published and committed to a policy. Enforcement still happens at the application layer, where each payment is checked against the committed rules before it is allowed. The hash does not make an out-of-policy transaction physically impossible to sign.

Making it impossible is the next layer: move policy enforcement to the signing key itself, inside a trusted execution environment, so a transaction that violates the constitution cannot be produced at all. The constitution is the public, verifiable contract; key-level policy is what turns "committed to" into "cannot exceed." The first is shippable today and stands on its own; the second builds on it.

One more input to Know Your Agent

A committed, verified constitution is a real risk signal. An agent that has publicly bound itself to a 1,000 USD per-transaction cap is in a different class from one with no declared limits. It joins identity and reputation as a third axis of the KYA trust score, and like the rest of the score it is deterministic and reproducible, not a black box.

Know Your Agent, before money moves

Verify identity, screen for sanctions, score any agent wallet 0-100, then settle to EUR. Free to query, no signup.

How KYA works Read the docs