Docs Objects
Risk assessment
LiveUpdated
Sellers and Agents. Written for merchants that receive agent orders and people who build agents, the hosts they run in, and the people and companies the agents pay for.
Today a merchant’s risk_signals are whatever the agent platform reports about itself. The risk assessment is made by Enruta at decision time, signed, verifiable with the mandate, and shaped to drop into the enumerations merchants and PSPs already use.
Fields
| Field | Contents |
|---|---|
id, policy_version, policy_hash | rsk_01M2511ZB2K6Q9W3T7N4B8D1XR; one assessment per decision |
checks[]{name, result, detail} | result: PASS · FAIL · SKIP. The seven policy checks (payee_allowlist, per_payment_cap, cumulative_budget_atomic, time_window, category, duplicate_idempotency, sanctions_screen, which reports SKIP while no live screening list is connected); since 0.3 the trust checks intent_coverage, intent_rules, intent_model, agent_identity, payee_identity and collateral; plus velocity (more than 5 requests by the agent in 60 s fails), catalog_snapshot_match (skipped unless the request carried catalog_snapshot_hash) and deviation_from_intent (skipped unless a maximum amount was given; fails when the amount exceeds it) |
agent_identity{kya_attestation_id, method, verification_status, assurance} | From the agent’s anchors and attestations: verified · unverified · stale, and the assurance level A0 to A3 |
principal_binding{principal_id_readable, approval_event_id} | The login id, and the approval event once a step-up completes |
score | 0 to 100, 0 = no risk: +40 per failed hard check, +15 for a first-time payee, +10 for a velocity failure, capped at 100 |
action | authorized · manual_review (step-up) · blocked (deny), the same words ACP and Adyen use |
signals_for_merchant | { amount_within_mandate, payee_in_mandate, human_approved, first_time_payee, agent_session_age_seconds }, the disclosable subset |
The assessment is decision.risk in the record and is signed by Enruta inside the bundle (signatures.risk, over the JCS digest of the object); the verifier checks that signature. Confirmations inside a model’s UI are not an input: a host’s “Allow once” button has no amount, payee, expiry or signature.
How the merchant sees it
When the Accept middleware reports an order or a merchant calls POST /v0/sellers/orders, the answer carries a risk_signals entry the merchant can store next to its PSP’s own:
"risk_signals": [{
"type": "enruta_mandate_verified",
"score": 0,
"metadata": {
"enruta_record": "https://api.enruta.ai/v0/records/rec_01M25129GZMJXTNQ47TMZRDGHN",
"mandate": "mnd_01M2512M8FQ7ZK4T1V9W3N6BXC",
"human_approved": false,
"amount_within_mandate": true,
"payee_in_mandate": true
}
}]When the agent’s Web Bot Auth signature verified, the middleware also adds { type: "web_bot_auth_verified", protocol, agent_origin, keyid, tag } to the risk signals it sends with the order, and when its UCP agent-profile signature verified, { type: "ucp_signature_verified", profile_url, keyid, alg } (Accept middleware).
Two examples
Policy: $200 a payment, $1,000 a month, a person above $150. The agent requests $180: per_payment_cap PASS, cumulative_budget_atomic PASS (820.00 remaining), approval required → step_up, action: manual_review, score: 0. The person who approves signs; principal_binding.approval_event_id is filled in, action becomes authorized, signals_for_merchant.human_approved: true.
The same agent requests $180 from the same payee thirty seconds later: duplicate_idempotency FAIL, action: blocked, score: 40. The denial is sealed with its assessment like any other decision.
Interfaces
| Surface | Where |
|---|---|
| Records | decision.risk on every payment record since enruta/0.2; signatures.risk in the bundle |
| REST | risk summary on POST /v0/payment-requests and GET /v0/payment-requests/{id}; risk_signals on POST /v0/sellers/orders and GET /v0/sellers/orders/{id} |
| MCP | risk: { action, score } in every payment result |
| Console | The checks table on /payments/{account}/payments/{id}; the risk signal on the seller’s order page |