Enruta

Docs · Concepts

Trust model

LiveUpdated

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.

Identity and intent are checked separately. Intent is decided on the user’s side: the agent’s request becomes slots, rules, an optional model and questions, and Enruta signs a mandate for the merchant. Identity is checked both ways: the merchant checks the agent’s anchors, and the agent’s side checks the merchant’s domain, keys and signature. Money moves on the rail and the PSP, never through Enruta.Intentdecided on the user’s sideUserAgentEnrutaMerchantasksrequestsigned mandateslotsrulesmodelquestionsIdentitychecked both waysthe merchant checks the agentthe agent’s side checks the merchantkeycoderuntimeentitydomainkeyssignatureRail · PSPthe money moves here, never through Enruta

Two axes

IdentityIntent
The questionWhich agent, running where, answering to whomIs this payment what the person asked for, within what they authorized
Who checks itBoth sides: the merchant checks the agent, and the agent’s side checks the merchantThe user’s side only, under the policy the user signed
What it rests onAnchors: a key and a code digest the agent carries; a runtime and a legal entity, or collateral, it borrowsThe person’s words as slots, rules, a model for what rules cannot decide, and questions for what is missing
What the merchant receivesThe mandate, and the identity of the agent presenting itOnly the outcome: a mandate Enruta signed
In the recordagent.identity, payee.identityrequest.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 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.

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:

KindAnchorWhat it proves`type`
CarriedA private keyRequests come from the key bound to this agentagent_key
CarriedA code digestWhich build of the agent runscode_digest
Borrowed: where it runsA workload identity token, or a hardware attestationThe build ran in a known CI job, cloud project or enclaveworkload_identity, hardware_attestation
Borrowed: who answersA legal entity that someone else verifiedA person or a company is accountable for the agentlegal_entity
Borrowed: who answers, on crypto railsCollateral on chainValue that can be claimed if the agent misbehavescollateral

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 says how each one is verified.

  • 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

PartyAnswers forAnchors
The developer who wrote the agentThe codelegal_entity with party: developer; code_digest
The platform that runs the agentWhere and how it runslegal_entity with party: platform; workload_identity or hardware_attestation
The user who gave the instructionThe authorizationlegal_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 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

SurfaceWhat you see
Record, enruta/0.3request.intent, decision.judgement, agent.identity, payee.identity; the raw anchor evidence and the model’s input and output in the bundle (schema)
RESTPOST /v0/payment-requests/{id}/clarifications, GET /v0/merchants/identity?domain=, POST /v0/attestations, GET /v0/agents/{id}/identity
MCPanswer_clarification, verify_merchant; the decision card shows the questions, the agent’s assurance level and the merchant check
ConsoleThe Intent, Judgement and Identity panels on a payment; the anchors on an agent’s page