# Trust model

Two questions decide whether an agent may pay: who the agent is, and whether this payment is what the person meant. Enruta answers them separately, checks identity in both directions, and seals how each answer was reached.

Status: Live · Updated: 2026-09-14
Source: https://enruta.ai/docs/trust-model

Every agent payment raises two separate questions. **Identity**: which agent is this, where does it run, and who answers for it? **Intent**: is this payment what the person asked for, inside what they authorized? The two are independent. A well-identified agent can still buy the wrong thing, and a purchase that matches the request can still come from an agent nobody can hold to account. Enruta checks both, keeps them apart, and seals how each was decided.

(Figure: trust-model)

## Two axes

|  | Identity | Intent |
|---|---|---|
| The question | Which agent, running where, answering to whom | Is this payment what the person asked for, within what they authorized |
| Who checks it | Both sides: the merchant checks the agent, and the agent’s side checks the merchant | The user’s side only, under the policy the user signed |
| What it rests on | Anchors: a key and a code digest the agent carries; a runtime and a legal entity, or collateral, it borrows | The person’s words as slots, rules, a model for what rules cannot decide, and questions for what is missing |
| What the merchant receives | The mandate, and the identity of the agent presenting it | Only the outcome: a mandate Enruta signed |
| In the record | `agent.identity`, `payee.identity` | `request.intent`, `decision.judgement` |

## The merchant checks identity, not intent

Intent is decided once, on the user’s side, by the policy the user signed. The merchant does not judge it again. It receives the result as a mandate signed by Enruta and bound to the checkout, the amount and the payee, and verifies that signature at its edge with the [Accept middleware](https://enruta.ai/docs/accept-middleware) or `POST /v0/sellers/verify`. What the merchant does check is identity: that the mandate is genuine and which agent presents it.

## Identity is checked in both directions

Before the agent pays, Enruta checks the merchant: the domain answers over TLS and its UCP profile names that domain, the profile publishes signing keys, the checkout’s `ap2.merchant_authorization` verifies against those keys, a seller organization has verified the domain, and the domain’s latest conformance run passed. The result is sealed in the payment record as `payee.identity`, a top-level object rather than part of `request.payee`, and a policy can require a verified merchant above an amount with `payee_identity.require_verified_above`.

```http
GET /v0/merchants/identity?domain=reamandrule.com
{
  "domain": "reamandrule.com",
  "status": "verified",
  "checks": [
    { "name": "domain", "result": "PASS" },
    { "name": "ucp_keys", "result": "PASS" },
    { "name": "checkout_signature", "result": "SKIP", "detail": "no checkout" },
    { "name": "seller_org", "result": "PASS" },
    { "name": "conformance", "result": "PASS" }
  ],
  "seller_org": "org_ream_and_rule",
  "checked_at": "2026-09-14T09:12:03Z"
}
```

`verified` needs the domain and the keys to pass and the checkout signature not to fail. A checkout whose merchant signature fails is `mismatch`: the payment is denied with `payee_identity_mismatch`, and the denial is sealed. When a policy requires a verified merchant and the check cannot verify it, `payee_unverified` steps up or denies, as the policy’s `on_fail` says. MCP `verify_merchant` and `enruta merchant verify <domain>` make the same check.

## Why identity needs borrowed anchors

An agent is software. It can be copied, moved and run in many places at once, so nothing the agent carries by itself proves that the same agent is running in a controlled environment on behalf of someone accountable. A private key proves who signed; a code digest proves which build. Neither says where it ran or who answers for it. Identity is therefore built from two kinds of anchor:

| Kind | Anchor | What it proves | `type` |
|---|---|---|---|
| Carried | A private key | Requests come from the key bound to this agent | `agent_key` |
| Carried | A code digest | Which build of the agent runs | `code_digest` |
| Borrowed: where it runs | A workload identity token, or a hardware attestation | The build ran in a known CI job, cloud project or enclave | `workload_identity`, `hardware_attestation` |
| Borrowed: who answers | A legal entity that someone else verified | A person or a company is accountable for the agent | `legal_entity` |
| Borrowed: who answers, on crypto rails | Collateral on chain | Value that can be claimed if the agent misbehaves | `collateral` |

The anchors add up to an assurance level, from `A0` (nothing verified) to `A3` (a verified key plus a verified legal entity, or, on x402 or MPP, plus verified collateral that covers the amount). Every new payment record carries it, `A0` when the agent has no anchors. [Identity anchors](https://enruta.ai/docs/identity-anchors) says how each one is verified.

## Card and bank rails link a legal entity; crypto rails use collateral

- **On card, bank and account rails** the anchor that counts is a legal entity, for three reasons: anti-money-laundering rules require a known customer, accountability needs someone to hold to it, and a spending limit is priced on who stands behind it. Enruta reads the verification the rail or the platform already performed, such as a Stripe Issuing cardholder or an organization’s own verification, and seals it. It never collects identity documents.
- **On crypto rails**, x402 and MPP, a payment does not have to be tied to a person. The anchor is economic: a deposit or a stake that the agent’s operator has locked in an escrow or bond contract. Enruta reads the balance on chain when it decides; it never holds keys or funds.

## Three parties can be linked

| Party | Answers for | Anchors |
|---|---|---|
| The developer who wrote the agent | The code | `legal_entity` with `party: developer`; `code_digest` |
| The platform that runs the agent | Where and how it runs | `legal_entity` with `party: platform`; `workload_identity` or `hardware_attestation` |
| The user who gave the instruction | The authorization | `legal_entity` with `party: user` |

A policy prices limits on these anchors. Rows in `identity_requirements` ask for stronger anchors as the amount grows, for example a key for small payments, a key and a workload identity above $100, and the user’s legal entity above $1,000, and step up or deny when an anchor is missing (`identity_insufficient`).

## Intent: reduce the words, then judge

What has to be checked is natural language, not a yes-or-no value. Enruta reduces it first and judges second:

1. **Structure.** The person’s words become slots: category, items, quantity, unit and total maximum, payee, deliver-by date, whether substitutions are allowed, recurrence.
2. **Rules first.** Whatever a rule can decide, a rule decides: `quantity lte 10`, `payee in [reamandrule.com]`, `max_total lte 200.00`.
3. **A model for the rest.** What rules cannot decide, such as whether a label maker counts as office supplies, goes to a model that is separate from the agent placing the order, and only when the policy turns it on. The hashes of the model’s input and output are sealed in the record.
4. **Questions for the gaps.** When the words do not cover what the policy needs (“buy some printer paper”, with no quantity and no budget), the decision is `clarify` with a list of questions. The agent asks the person, and the answers go into the record before the request is decided again.

A decision has one of three outcomes: `allow`, `step_up` (a person confirms) or `deny`. `observe` (shadow mode) and `clarify` are states around a decision, not a fourth outcome. [Intent and clarification](https://enruta.ai/docs/intent-and-clarification) has the fields.

## What Enruta does not do

- Run a registry of agents. Anchors come from issuers that already exist, such as a key the agent controls, a CI provider’s OIDC token, a cloud enclave or a rail’s verification.
- Collect identity documents or run KYC. A legal-entity anchor reads a verification someone else performed.
- Hold collateral or keys. A collateral anchor is a read of a contract’s balance.
- Ask the merchant to judge intent. The merchant verifies the mandate; the user’s policy decided the payment.

## Where it shows

| Surface | What you see |
|---|---|
| Record, `enruta/0.3` | `request.intent`, `decision.judgement`, `agent.identity`, `payee.identity`; the raw anchor evidence and the model’s input and output in the bundle ([schema](https://enruta.ai/docs/schema)) |
| REST | `POST /v0/payment-requests/{id}/clarifications`, `GET /v0/merchants/identity?domain=`, `POST /v0/attestations`, `GET /v0/agents/{id}/identity` |
| MCP | `answer_clarification`, `verify_merchant`; the decision card shows the questions, the agent’s assurance level and the merchant check |
| Console | The Intent, Judgement and Identity panels on a payment; the anchors on an agent’s page |
