Add ERC: Unclonable Agent Execution Credentials - #1953
Conversation
File
|
ethereum/ERCs#1953 is open as a draft, so the pull request number convention settles the number. Replaces the ERC-XXXX placeholder in the two domain separation tags and every reference to it, across the spec, the proposal, the Guards, the libraries, the Noir circuit notes, the vendored assets, and all four test files. test_CommitmentParity was tautological. It compared a test-local literal against the same test-local literal and never touched CapabilityCommitment, so it could not catch the exact drift it existed to catch. It now compares the library output against the vector written into the proposal, and test_FixtureParity pins the hand-built fixtures to the library too. Verified by mutation: changing CAPABILITY_TAG in the library fails both, restoring it passes both. 20 tests green.
The two tags carried an ERC-XXXX placeholder. Now that this pull request has a number, they read ERC-1953 in the proposal and in the vendored reference implementation. Both strings must match byte for byte between Guard and circuit, so the wording under Constants now says so rather than describing a placeholder.
|
The commit c4687e9 (as a parent of d576371) contains errors. |
HTMLProofer failed on ethereum/ERCs#1953 with six broken internal links. The Merge Repos step in ci.yml renames every assets/erc-* directory to assets/eip-* before Jekyll builds, so ../assets/erc-1953/... points at a path that does not exist in the built site. The directory committed to the repository stays assets/erc-1953/. Only the links change. Confirmed against the merged corpus: 209 of 210 asset directories are named erc-* on disk while 499 of 499 asset links in merged proposals are written eip-*. Verified by reproducing the CI rename locally and resolving each of the six links against it, rather than assuming.
HTMLProofer reported six broken internal links. The Merge Repos step in ci.yml renames assets/erc-* to assets/eip-* before Jekyll builds, so ../assets/erc-1953/ does not exist in the built site. The committed directory name is unchanged.
|
Good to see this land as a formal PR -- the thread's arc (separable One place worth pinning down: "authorization soundness" is named as the layer this proposal explicitly does not supply (§ Security Considerations, "Unclonability and authorization soundness are orthogonal"). Is that meant to cover both (a) whether the issuing policy was actually followed, and (b) whether the resulting authorized action was itself a good decision? Those are different failure modes with different fixes -- a confidential policy verdict (CAPV / ERC-8354) can prove (a) without ever touching (b). We ran into the same split on the CAPV thread (https://ethereum-magicians.org/t/29088/54, replying to a similar "does ZK add anything over signing" question): ZK removes trust in the definer's honesty about execution, but that's compliance-with-policy, not soundness-of-the-outcome -- a policy can be followed to the letter and still authorize something bad. Not proposing a change to scope, just flagging that if "authorization soundness" reads as one property to an implementer, a deployment wiring in ERC-8354 alone could believe it's covered both axes when it's only closed the first. Might be worth a clause distinguishing them, the same way the doc already separates unclonability from soundness. |
Co-authored-by: Andrew B Coathup <28278242+abcoathup@users.noreply.github.com>
Co-authored-by: Andrew B Coathup <28278242+abcoathup@users.noreply.github.com>
This proposal defines a single use capability token for delegated agent execution. An orchestrator issues a capability bound to an agent identity and a per issuance secret salt. Spending it requires a zero-knowledge proof, which forces a nullifier derived from that salt into the open, and the Guard burns the nullifier as part of performing the authorized action. A cloned agent holds the same salt, produces the same nullifier, and is rejected.
The idea was discussed on Ethereum Magicians before this PR was opened:
https://ethereum-magicians.org/t/idea-draft-erc-unclonable-agent-execution-credentials-via-zero-knowledge-nullifiers/29274
That thread ran for two weeks and changed the design three times. The substantive points and where each landed:
chainIdmust not be in the nullifier preimage, or the nullifier forks per chain and the credential is spendable once on each. Chain binding is now an acceptance check onhomeChainIdinstead.highestIssuedIndexto classify a collision as a clone versus an issuer reissue bug.The reference implementation lives at https://github.com/mzf11125/unclonable-agent-execution-credentials and the Solidity sources are also vendored into
assets/erc-1953/, so the proposal body carries no external links. Nineteen Foundry tests cover the cases in the Test Cases section, including the adversarial vectors from the thread.Known open questions, stated rather than hidden:
msg.sender == executor, so an agent holding no gas cannot spend through a relayer. Adding an EIP-712 path needs a signature argument onexecute, which changes the interface, so it is deferred.All authors listed in the preamble have consented to CC0 licensing and to being named.