Giving an autonomous AI agent an unconstrained private key creates critical attack vectors: prompt injection, model hallucinations, and RPC interception. Traditional ERC-4337 accounts solve this via custom validator modules, but require migrating assets into an abstract contract wallet.
With ERC-7702, an existing Externally Owned Account (EOA) can delegate its code execution to an implementation contract for a single transaction or session using the EIP-7702 authorization list format:
Authorization Tuple = (chainId, contractAddress, nonce, yParity, r, s)
When evaluated, the EVM prefixes the account bytecode with 0xef01 followed by the designated code address. We can deploy a dedicated AgentSessionValidator contract that enforces temporal limits, target contract whitelisting, and daily spending allowances.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract AgentSessionValidator {
struct SessionConfig {
address agentKey;
uint48 validUntil;
uint96 spendLimit;
uint96 totalSpent;
bytes4 allowedSelector;
address allowedTarget;
}
mapping(address => mapping(bytes32 => SessionConfig)) public sessions;
error SessionExpired();
error UnauthorizedTarget();
error SpendLimitExceeded();
function executeWithSession(
bytes32 sessionId,
address target,
uint256 value,
bytes calldata payload,
bytes calldata agentSignature
) external payable returns (bytes memory) {
SessionConfig storage config = sessions[msg.sender][sessionId];
if (block.timestamp > config.validUntil) revert SessionExpired();
if (target != config.allowedTarget) revert UnauthorizedTarget();
if (bytes4(payload[:4]) != config.allowedSelector) revert UnauthorizedTarget();
if (config.totalSpent + value > config.spendLimit) revert SpendLimitExceeded();
bytes32 digest = keccak256(abi.encodePacked(block.chainid, target, value, payload));
bytes32 ethSignedDigest = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", digest));
address recovered = ecrecover(ethSignedDigest, uint8(agentSignature[64]), bytes32(agentSignature[:32]), bytes32(agentSignature[32:64]));
require(recovered == config.agentKey, "Invalid Agent Sig");
config.totalSpent += uint96(value);
(bool success, bytes memory result) = target.call{value: value}(payload);
require(success, "Execution Failed");
return result;
}
}
Ephemeral Key Lifecycle
-
Instantiation: The human user signs an EIP-712 payload authorizing an ephemeral
agentKey(generated in memory on the agent's isolated runtime) with strict execution boundaries (validUntil = block.timestamp + 1800,spendLimit = 0.5 ether). - Execution: The agent queries an on-chain DEX or lending market, computes the optimal route, signs the calldata using its memory-bound key, and broadcasts via an ERC-7702 authorization batch.
- Revocation & Expiry: Once completed or upon TTL expiry, the session invalidates automatically. A single on-chain nullifier write can kill the session instantly if an anomaly is detected by an external watchdog.
Top comments (0)