BotanaryBotanary
Rules

Rules & AgentGuard

AgentGuard is the on-chain policy engine that enforces the owner's own caps, allowlists, and freeze state.

Account rules govern the owner's own actions - what you, sending directly from your own account, are allowed to do. They're enforced on-chain by AgentGuard, and they're a different mechanism from a delegation's policy, even though both exist to keep authority bounded.

What AgentGuard is

AgentGuard is a hook installed on your account's root validator - the same OwnableValidator that your owner and device keys sign through. It runs in the execution phase, after an operation has already been accepted, which is what lets it enforce things a delegation's validation-phase policy structurally can't - most importantly, rolling time windows (see below). There's no separate, account-global hook slot to install it into; the root validator is the only place a hook can sit, so AgentGuard and your signing validator are necessarily the same module.

AgentGuard governs the owner's own lane. A delegate's authority is governed by its own delegation policy instead - see Delegations. The two are enforced at different points and by different mechanisms.

Installing and updating

The first time you ever set a rule, the operation does two things atomically: it installs AgentGuard as your root validator's hook, and it seeds it with your first set of rules. Every change after that is just a batch of ordinary setter calls against the already-installed hook - no reinstall involved.

A fresh install seeds a default set of permitted stablecoins for your chain, so turning rules on in the first place never silently narrows what you could already move. And a rules update that would change nothing is rejected outright rather than asking you to sign a no-op.

Once AgentGuard is installed, every owner operation has to be wrapped in a specific execute frame the module expects, or the account rejects it in validation - this is applied automatically, not something you construct yourself.

Rolling windows are honest here, not on a delegation

Because AgentGuard's hook runs in execution, it's legal for it to read the current block time - which is exactly what a "per day," "per week," or "per month" spending cap needs. A delegation's policy, checked in ERC-4337 validation, is not allowed to do that at all, which is why a delegation's budget is always a lifetime total instead. See Delegations for that contrast in full.

Evaluation order

When a proposed action is checked against your rules, a denylist entry always wins over an allowlist entry - a denied contract or recipient is refused even if it also happens to be allowlisted. The full advisory check runs in this order: is the account frozen, is the contract denied, is the recipient denied, is the contract missing from a non-empty allowlist, is the recipient missing from a non-empty allowlist, and finally, does the amount exceed the cap. This mirrors the order the on-chain hook itself checks in.

Lowering a cap or removing an allow or deny entry is always treated as risk-reducing, which keeps that change gasless too, just like a freeze - tightening your own rules never costs you gas.

Freezing

Freezing your account is the one true kill switch, and it's the only freeze that exists anywhere in the system - there's no way to freeze a single delegation on its own (see Revoking a delegation). The freeze setter stays reachable even while the account is already frozen, because it's also how you unfreeze.

See Constraint types for the full list of what AgentGuard can bind, and Simulation for how a proposed action gets checked against these rules before you're ever asked to sign it.

On this page