AI agents · DeFi execution · Policy enforcement
Agents can move funds. This decides which moves are allowed.
SecureAgent sits between an AI agent and the chain.
Every transaction is decoded, evaluated against policy, and allowed, held for approval, or blocked.
Supported today
Integrations that work today. Not customers, not endorsements.
- SafeSafe-aware batch decoding
- MorphoERC-4626 vault deposits
- Uniswap V3SwapRouter02 swaps
- ERC-20Approvals
- Chain agnosticPolicy is evaluated on decoded calldata
The stakes
An agent mistake is a settled transaction.
A hallucinated token address, a wrong recipient, a misread balance. In a chat window these are bad outputs and get corrected. Once the agent can sign, each one is an irreversible transfer.
The agent is a co-signer, never the key holder.
That part is already understood. SecureAgent holds no key either. It decides whether a call is permitted at all, before anyone signs.
The permission surface is where the risk now lives.
The set of things a co-signing agent may do is the attack surface. Most teams express it as a short allow-list and find the gaps in production.
Example evaluation
Decoded before it is judged.
Static sample data shipped with this page. No network calls.
Morpho vault deposit
Case 1 of 3Base · 8453
A deposit into a curated Morpho vault, receiver is the Safe itself.
| chain | Base 8453 |
|---|---|
| target | Steakhouse USDC vault0xbeefa7b88064feef0cee02aaebbd95d30df3878fMorpho ERC-4626, in lend/morpho registry |
| selector | 0x6e553f65deposit(uint256, |
| decoded arguments | |
| assets | uint2562,500.000000 USDC |
| receiver | addressown Safemust equal the Safe |
| value | 0 ETH |
| value (simulated) | $2,500.00 (USDC parity) |
checks
- rule matchpass
- expected
- at least one matching rule
- actual
- morpho/erc4626-deposit
- arg constraintspass
- expected
- receiver == own Safe
- actual
- own Safe
- per-tx USD cappass
- expected
- ≤ $5,000.00
- actual
- $2,500.00
- total-deposit cappass
- expected
- ≤ $50,000.00 per 24h
- actual
- $14,300.00 after this tx
- recipientspass
- expected
- value stays in own Safe
- actual
- own Safe
- verdict
- ALLOW
- rule that decided
all checks passedMatched morpho/erc4626-deposit. Amount within the per-transaction and cumulative caps. Value stays inside the Safe.
What it does
What SecureAgent does
Decode
Every call is decoded to its function selector and arguments before it is judged. Safe batches are unwrapped and each inner call is evaluated on its own. Nothing is judged by its envelope.
Decide
Rules, not model judgement. Allowed protocols, allowed external destinations, selector allow-lists, allowance ceilings, per-transaction and cumulative size limits. A dry run validates the call before execution. The same input always yields the same verdict.
Delegate
A call the rules mark for review goes to a named person. The approver sees the decoded call, not raw calldata. Nothing executes until they answer.
The agent never holds the key. It still needs a boundary.
SecureAgent is a policy gate. It sits between the agent and the signer, decides per call, and never signs.
Request
The agent proposes a transaction: target contract, calldata, value. At most it holds a co-signer key. It never holds a key that moves funds alone.
Step 1 of 4: Request
- 01Agent
- 02SecureAgent
- 03Policy evaluation
- 04Signer
SecureAgent never holds a private key and never signs. It is software that runs inside your system.
The guarantee holds only if the gate is the only path.
An agent that can call a public RPC endpoint directly, or that holds a key able to sign alone, is not behind the gate. Closing those paths is part of deployment. SecureAgent's guarantee is stated on that condition.
Decode the inner call. Then decide.
A Safe transaction can carry many calls in one envelope. From the outside, the envelope looks like a routine call to a known contract. What matters is inside.
Outer envelope
Safe transaction
execTransaction to the canonical Safe MultiSendCallOnly contract, value 0.
- to
- Safe MultiSendCallOnlycanonical Safe contract
- value
- 0 ETH
- selector
- 0x8d80ff0a multiSend(bytes)
- operation
- DELEGATECALLstandard for MultiSend
Known contract. No ETH. A routine batch. Judged by the envelope alone, this would look benign.
Inner calls, evaluated one by one
call 1USDC0x833589fcd6edb6e08f4c7c32d4f71b54bda02913
0x095ea7b3approve(address,uint256)
- spender
- 0xbeef…878fSteakhouse USDC vault
- amount
- 2,500.000000 USDC
ALLOWerc20/approve-to-morpho-vaults
Exact amount, spender in the lend/morpho registry.
call 2Steakhouse USDC vault0xbeefa7b88064feef0cee02aaebbd95d30df3878f
0x6e553f65deposit(uint256,address)
- assets
- 2,500.000000 USDC
- receiver
- own Safe
ALLOWmorpho/erc4626-deposit
Receiver is the Safe. Within the per-transaction cap.
call 3USDC0x833589fcd6edb6e08f4c7c32d4f71b54bda02913
0xa9059cbbtransfer(address,uint256)
- to
- external addressnot in allowed_external
- amount
- 250,000.000000 USDC
BLOCKrule match
No rule permits transfer(address,uint256) on USDC, and the destination is outside the allow-list. Default is deny.
- call 1ALLOW
- call 2ALLOW
- call 3BLOCK
worst inner call
Call 3 fails. The whole batch is refused. Nothing in it executes.
A batch is judged by its worst inner call, never by its envelope.
The failure class this answers
Several of the largest multisig compromises, including Bybit, WazirX, and Radiant Capital, followed one pattern. A signer approved a transaction whose real effect was not visible at signing time. The call looked routine. Its inner effect changed ownership or drained a contract.
Decoding and evaluating each inner call before signing is a direct response to that class of failure. It is not a guarantee against every loss. It is a check that the call you approve is the call that executes.
A policy gate is not a signer threshold.
Two different controls. Both matter. They answer different questions and the page keeps them apart.
SecureAgent is this.
Policy gate
Decides whether a call is permitted at all.
Evaluates the decoded call against rules: destination, protocol, selector, allowance, size. Output is allow, hold, or block.
Your multisig is this.
Signer threshold
Decides how many keys must sign.
A 2-of-3 multisig needs two signatures. It does not inspect what is being signed. It is a quorum, not a judgement.
counts signatures, does not read the call
SecureAgent sits in front of any signer arrangement. It does not replace one, and it does not lower the threshold.
Allow, hold, block
- ALLOW
Allow
Every rule passes. The call proceeds to your signer. Nobody is asked.
- HOLD
Hold for approval
A rule marks the call for review, such as a size above the automatic limit. A named approver sees the decoded call and decides. Nothing executes until they do.
- BLOCK
Block
A rule fails outright: an unlimited allowance, an unknown selector, a destination outside the allow-list. The call is refused and the rule is reported to the agent.
Who gets asked, and when
| Condition | Verdict | Who decides |
|---|---|---|
| Inside every rule | ALLOW | Nobody. Automatic. |
| Above the automatic size limit, below the hard limit | HOLD | A named approver. |
| Outside a rule | BLOCK | Nobody. Refused, rule reported. |
| Cannot be decoded | BLOCK | Nobody. Fails closed. |
Policy example
Rules you can read.
A policy is a file, not a prompt. Allowed protocols, allowed external destinations, a selector allow-list, an allowance ceiling, and per-transaction and cumulative size limits.
Illustrative
The schema is not final. This shows the shape of a policy, not the API.
# SecureAgent policy (illustrative; schema not final)name: treasury-agentchains: - 8453 # Base protocols: allowed: - morpho # ERC-4626 vaults - uniswap-v3 # SwapRouter02 - erc20 # approvals only destinations: # External addresses the agent may send value to. # Empty means funds may only ever return to the Safe itself. allowed_external: [] selectors: allow: - "0x6e553f65" # deposit(uint256,address) Morpho - "0xb460af94" # withdraw(uint256,address,address) Morpho - "0x095ea7b3" # approve(address,uint256) ERC-20 - "0x04e45aaf" # exactInputSingle((...)) Uniswap V3 # Any other selector is blocked. There is no default-allow. allowances: max_approve_usd: 5000 # approve() above this is blocked reject_unlimited: true # raw amount > 2^80 is blocked outright limits: per_tx_usd: allow_below: 5000 # ALLOW automatically hold_below: 25000 # HOLD for a named approver # above hold_below: BLOCK cumulative_usd: window: 24h max: 50000 max_txs_per_hour: 20 approval: approvers: - "TODO(ilyes): approver identity"Why not build it
You could build this yourself.
Most teams do, as an allow-list inside the agent. Here is what that gets you, what it misses, and where a separate enforcement point differs.
| Dimension | An in-house allow-list | SecureAgent |
|---|---|---|
| What it checks | The target address. Sometimes the function name. | The selector and every decoded argument, per call. |
| Batched calls | The envelope. A Safe batch is one transaction to one contract. | Each inner call, unwrapped and judged on its own. |
| Limits | Usually one per-call cap. | Per-transaction and cumulative size, plus an allowance ceiling. |
| Who it constrains | The agent's code path. An engineer with deploy access changes the list. | Any party operating the agent. The control is independent of who runs it. |
| Failure mode | Shared with the agent. Same deploy, same bug surface. | Separate. A second layer with its own failure mode, which is the argument for defence in depth. |
| Verdict | Often a model call or an ad-hoc condition. | Rule-based and deterministic. Same input, same verdict, every time. |
What an in-house allow-list gets you
A fast first control that you fully understand. For one protocol and a small, trusted team, it may be enough. SecureAgent does not replace your own checks. It adds a second enforcement point that does not share their failure mode.
Who it is for
Three teams, one boundary.
Agent platforms
Your end users run agents over their own funds. You expose policy configuration in your product. SecureAgent enforces it underneath, per call.
Treasury and yield automation
An agent moves funds between protocols. You need hard bounds on destinations, protocols, and size, and a person in the loop above a threshold.
Adding execution to an existing agent
Your agent already reads and reasons. Before it can sign anything, its permission surface has to be defined and enforced outside the agent's own code.
Deployment
Runs where your keys are.
Licensed software in your infrastructure
SecureAgent runs inside your system, next to your agent and your signer. It never holds a private key and never signs.
Hosted service
The same policy gate, operated as a service. Your agent submits calls; your signer receives only what the policy allows.
Both are available today. Which one fits depends on where your signer already runs.
Provenance
Built at Nethermind.
SecureAgent is built at Nethermind, where security engineering is a core practice alongside blockchain infrastructure such as the Nethermind Ethereum execution client. That is provenance, not a badge. It is not a certification and it is not a trust mark for products that use SecureAgent.
The architecture is off-chain and reviewable. It is designed so that an independent reviewer can check that an operator cannot quietly route funds around the policy. No third-party review has been carried out yet, so that is a property of the design, not a result anyone has confirmed.
Contact
Get in contact.
Tell us what your agent needs to be allowed to do. We will reply by email.
We use what you send here only to reply to you. No newsletter, no tracking.
Or emaililyes.jeridi@nethermind.io