You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every limit the agent operates under today is enforced by the daemon's policy gate — software. This issue makes the limits chain-enforced: the user's EOA reversibly delegates (EIP-7702) to an audited contract, and the agent's session key physically cannot exceed its cap, outlive its expiry, or touch a non-allowlisted target — even if the daemon's software fence were gone. Verified white space (research 2026-06-11): Kohaku has no 7702/session-key work, eth-infinitism ships no scoped-key contract, Walletbeat marks scoped permissions as future work; MetaMask's Agent Wallet EAP (June 8, 2026) started the clock.
Decisions already made
No bundler, ever, in this scope. Both candidate stacks support the session key sending a plain, self-gas-paid transaction (verified in source):
Backend chosen at implementation time against these frozen criteria, in order: (1) assurance evidence at impl time (a Porto firm audit reopens the question), (2) Sepolia + mainnet deployment availability, (3) grant-card legibility, (4) reuse for x402's ERC-7710 settlement path. Grant/revoke/execute semantics below are backend-neutral so the choice doesn't churn the wire.
v1 scope (cut 2026-06-12):SessionScope = { per_tx_cap_wei, expiry_unix, allow_to, token } — the single per-tx cap is the only spend cap. Period caps and per-method granularity are deferred (both backends support them; pure additions later). Expiry and allowlist are not caps and not cuttable — a grant without them is unbounded authority.
7702 authorization signing with hard invariants: never sign chain_id = 0 (spec-valid on all chains — unconditional refusal); delegate address must be on a hardcoded, versioned allowlist of audited deployments — user-supplied delegates rejected unconditionally (>97% of early mainnet delegations were malicious sweepers, per Wintermute); self-sponsored delegation signs auth nonce +1 (the tx consumes the current nonce); un-delegation (address(0)) clears code not storage, so re-delegation across storage-incompatible implementations is refused.
SessionGrant → NeedsApproval always — no policy mode auto-grants authority. Grant card renders delegate identity + version and every scope field. RevokeAll/STOP additionally queues on-chain revokes for every live grant. Grant/revoke/expiry events go to the append-only audit log.
Acceptance on the anvil Sepolia fork (chosen backend deployed from source if no canonical Sepolia deployment):
S1 grant {cap 0.05 ETH, expiry 24 h, allowlist [A]} → NeedsApproval, card complete, approve → live
S2 session key sends a plain EIP-1559 tx within the cap to A → lands, gas paid by session EOA, no bundler process anywhere
S3 over-cap attempt → reverts on-chain (not a daemon Deny)
S4 target ∉ allowlist → reverts on-chain
S5 warp past expiry → reverts on-chain
S6 revoke (one tx) → retry of S2 reverts; local session key zeroized
S7 un-delegate to address(0) → EOA code empty, plain sends work as before
S8 grant naming an unpinned delegate → typed Deny, nothing signed
S9 authorization request with chain_id = 0 → refused, nothing signed
S10 transcript scan → no key bytes, no passphrase
KB correction in docs/research/01-landscape-2026.md: MetaMask Advanced Permissions = Early Access 2026-06-08, not shipped 2026-04-06.
Walletbeat rubric contribution (cut 2026-06-12 — revisit with shipped evidence).
Exporting a grant to an external agent runtime (the future smart-account-autonomous mode) — semantics are shaped so it later needs no wire change, but the key does not leave the daemon in v1.
Why
Every limit the agent operates under today is enforced by the daemon's policy gate — software. This issue makes the limits chain-enforced: the user's EOA reversibly delegates (EIP-7702) to an audited contract, and the agent's session key physically cannot exceed its cap, outlive its expiry, or touch a non-allowlisted target — even if the daemon's software fence were gone. Verified white space (research 2026-06-11): Kohaku has no 7702/session-key work, eth-infinitism ships no scoped-key contract, Walletbeat marks scoped permissions as future work; MetaMask's Agent Wallet EAP (June 8, 2026) started the clock.
Decisions already made
No bundler, ever, in this scope. Both candidate stacks support the session key sending a plain, self-gas-paid transaction (verified in source):
EIP7702StatelessDeleGator(stateless; EOA key stays root)IthacaAccount(on-chain key registry)authorize(Key)+setCanExecute+setSpendLimitDelegationManager.redeemDelegations, caveat-checkedexecuteexternal-caller path (opData = nonce ++ sig)disableDelegation(delegator-only, on-chain)revoke(keyHash)(self-call by admin key)Sources: https://github.com/MetaMask/delegation-framework · https://github.com/ithacaxyz/account
Backend chosen at implementation time against these frozen criteria, in order: (1) assurance evidence at impl time (a Porto firm audit reopens the question), (2) Sepolia + mainnet deployment availability, (3) grant-card legibility, (4) reuse for x402's ERC-7710 settlement path. Grant/revoke/execute semantics below are backend-neutral so the choice doesn't churn the wire.
v1 scope (cut 2026-06-12):
SessionScope = { per_tx_cap_wei, expiry_unix, allow_to, token }— the single per-tx cap is the only spend cap. Period caps and per-method granularity are deferred (both backends support them; pure additions later). Expiry and allowlist are not caps and not cuttable — a grant without them is unbounded authority.In scope
SessionGrant { scope }/SessionRevoke { key_id }indeckard-contractunder capability namesession-keys-7702(depends on Wire-contract evolution: Hello capability discovery + the five evolution rules #31; additive per its evolution rules).min(local policy, session scope).chain_id = 0(spec-valid on all chains — unconditional refusal); delegate address must be on a hardcoded, versioned allowlist of audited deployments — user-supplied delegates rejected unconditionally (>97% of early mainnet delegations were malicious sweepers, per Wintermute); self-sponsored delegation signs auth nonce +1 (the tx consumes the current nonce); un-delegation (address(0)) clears code not storage, so re-delegation across storage-incompatible implementations is refused.SessionGrant→NeedsApprovalalways — no policy mode auto-grants authority. Grant card renders delegate identity + version and every scope field.RevokeAll/STOP additionally queues on-chain revokes for every live grant. Grant/revoke/expiry events go to the append-only audit log.address(0)→ EOA code empty, plain sends work as beforechain_id = 0→ refused, nothing signeddocs/research/01-landscape-2026.md: MetaMask Advanced Permissions = Early Access 2026-06-08, not shipped 2026-04-06.Not in scope
smart-account-autonomousmode) — semantics are shaped so it later needs no wire change, but the key does not leave the daemon in v1.Definition of done
cargo fmt --all --checkclean;just checkgreen (both feature configs);cargo test --workspacegreen.Open questions