What is a policy?
A policy is a gateway-canonical set of rules that the guard engine evaluates against an incoming transaction intent. It binds to a specificpolicyId and chainId — no single policy spans multiple chains.
Every mutation of the rules set creates a new immutable snapshot (incremented version). The policyHash is a deterministic keccak256(JCS(body)) fingerprint of the policy body at that version.
Policy shape
allowedTargets are stored and compared lowercased.
Policy hash
ThepolicyHash is computed by:
- Strip ephemeral fields (
owner,createdAt,updatedAt,metadata) - Lowercase all entries in
allowedTargets - Serialize with JCS (RFC 8785) — canonical JSON
- Hash with
keccak256(utf8(jcs_string))
Guard rules engine
Evaluation order: target → selector → value → daily cap → simulation → threshold.
maxSlippageBpsis not enforced in v0.2. The field is stored in the policy body and included in thepolicyHash, but the guard engine does not evaluate it. Pilots settingmaxSlippageBpsshould treat it as a label for future enforcement (planned v0.3). Transactions will not be denied based on slippage in the current release.
dailyCapWei uses a rolling 24-hour window, not a calendar day.
The cap counts executed + anchored transactions in the last 86,400 seconds from the current
timestamp — not from midnight UTC. Compliance teams expecting a midnight reset should note this
distinction. Calendar-day reset is planned as an opt-in flag in v0.3.
fromaddress is not constrained in v0.2. Any address can submit a guard request for your policy. The policy rules constrain what the transaction can do (target, selector, value) — not which agent can request the guard. Per-caller allowlists (allowedCallers) are a v0.3 roadmap item.
CRUD
Policy State Machine
Every policy has astate field that follows a strict one-way progression:
policySource field in receipts
Chain binding
A policy binds to exactly onechainId. If a guard request arrives with a different chainId than the policy’s, the gateway returns HTTP 400 CHAIN_MISMATCH.
PolicyAnchor — Security Notes
ThePolicyAnchor contract is permissionless: any address can anchor any policyId string for any
operator address. The first caller wins the policyKey = keccak256(operatorAddress, policyId, chainId).
Front-running mitigation: The AgentChain gateway anchors your policy key immediately on creation
(best-effort, async). If the anchor call is delayed, a third party could theoretically claim your
policyKey before the gateway does. This is a testnet-only risk — the gateway has SLA anchoring
within 30 seconds of policy creation. For mainnet, EIP-712 signed anchor claims are planned (v0.3).
Anchoring does NOT affect guard enforcement — the gateway uses its database as the source of truth.
PolicyAnchor is an audit log, not a policy registry.
