forked from ethereum/EIPs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add EIP-5539: Revocation List Registry (ethereum#5539)
* add Revocation List Registry to EIPS Signed-off-by: Lauritz Leifermann <[email protected]> * fix category & move definitions section to specification Signed-off-by: Lauritz Leifermann <[email protected]> * pull request review Signed-off-by: Lauritz Leifermann <[email protected]> * chore: add discussion link * chore: reflect newest changes to functions, events, and fix link issue * chore: fix links for nonce and signed hash * chore: add signer addresses to signed methods * chore: remove old batch event * chore: missing comma Signed-off-by: Lauritz Leifermann <[email protected]> Co-authored-by: Dennis von der Bey <[email protected]> Co-authored-by: Philipp Bolte <[email protected]> Co-authored-by: Philipp Bolte <[email protected]>
- Loading branch information
1 parent
2c4d2db
commit 91a0974
Showing
1 changed file
with
252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
--- | ||
eip: 5539 | ||
title: Revocation List Registry | ||
description: Registry of revocation lists for revoking arbitrary data. | ||
author: Philipp Bolte (@strumswell), Lauritz Leifermann (@lleifermann), Dennis von der Bey (@DennisVonDerBey) | ||
discussions-to: https://ethereum-magicians.org/t/eip-5539-revocation-list-registry/10573 | ||
status: Draft | ||
type: Standards Track | ||
category: ERC | ||
created: 2022-08-26 | ||
requires: 712 | ||
--- | ||
|
||
## Abstract | ||
This EIP proposes a set of methods and standards for a role-based registry of indicators aimed for usage in revocations. | ||
|
||
## Motivation | ||
Revocation is a universally needed construct both in the traditional centralized and decentralized credential attestation. This EIP aims to provide an interface to standardize a decentralized approach to managing and resolving revocation states in a contract registry. | ||
|
||
The largest problem with traditional revocation lists is the centralized aspect of them. Most of the world's CRLs rely on HTTP servers as well as caching and are therefore vulnerable to known attack vectors in the traditional web space. This aspect severely weakens the underlying strong asymmetric key architecture in current PKI systems. | ||
|
||
In addition, issuers in existing CRL approaches are required to host an own instance of their public revocation list, as shared or centralized instances run the risk of misusage by the controlling entity. | ||
This incentivizes issuers to shift this responsibility to a third party, imposing the risk of even more centralization of the ecosystem (see Cloudflare, AWS). | ||
Ideally, issuers should be able to focus on their area of expertise, including ownership of their revocable material, instead of worrying about infrastructure. | ||
|
||
We see value in a future of the Internet where anyone can be an issuer of verifiable information. This proposal lays the groundwork for anyone to also own the lifecycle of this information to build trust in ecosystems. | ||
|
||
## Specification | ||
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119. | ||
|
||
This EIP specifies a contract called `EthereumRevocationRegistry` that is deployed once and may then be commonly used by everyone. By default, an Ethereum address **MAY** own and manage a multitude of revocation lists in a namespace that **MUST** contain the revocation states for a set of revocation keys. | ||
|
||
An owner of a namespace **MAY** allow delegates to manage one or more of its revocation lists. Delegates **MUST** be removable by the respective list's owner. In certain situations, an owner **MAY** also want to transfer a revocation list in a namespace and its management rights to a new owner. | ||
|
||
### Definitions | ||
- `namespace`: A namespace is a representation of an Ethereum address inside the registry that corresponds to its owners address. All revocation lists within a namespace are initially owned by the namespace's owner address. | ||
- `revocation list`: A namespace can contain a number of revocation lists. Each revocation list is identified by a unique key of the type bytes32 that can be used to address it in combination with the namespace address. | ||
- `revocation key`: A revocation list can contain a number of revocation keys of the type bytes32. In combination with the namespace address and the revocation list key, it resolves to a boolean value that indicates whether the revocation key is revoked or not. | ||
- `owner`: An Ethereum address that has modifying rights to revocation lists within its own and possibly foreign namespaces. An owner can give up modifying rights of revocation lists within its namespace by transferring ownership to another address. | ||
- `delegate`: An Ethereum address that received temporary access to a revocation list in a namespace. It has to be granted by the current owner of the revocation list in question. | ||
|
||
### Revocation Management | ||
|
||
#### isRevoked | ||
**MUST** implement a function that returns the revocation status of a particular revocation key in a namespace's revocation list. It **MAY** also respect the revocation lists revocation status. | ||
```solidity | ||
function isRevoked(address namespace, bytes32 list, bytes32 key) public view returns (bool); | ||
``` | ||
|
||
#### changeStatus | ||
**MUST** implement a function to change the revocation status of a particular revocation key in a namespace's revocation list | ||
```solidity | ||
function changeStatus(bool revoked, address namespace, bytes32 revocationList, bytes32 revocationKey) public; | ||
``` | ||
|
||
#### changeStatusSigned ([see Meta Transactions](#MetaTransactions)) | ||
**OPTIONAL** implements a function to change the revocation status of a particular revocation key in a namespace's revocation list with a raw signature. | ||
```solidity | ||
function changeStatusSigned(bool revoked, address namespace, bytes32 revocationList, bytes32 revocationKey, address signer, bytes calldata signature) public; | ||
``` | ||
|
||
#### changeStatusDelegated | ||
**OPTIONAL** implements a function to change the revocation status of a particular revocation key in a namespace's revocation list by a revocation list's delegate. | ||
```solidity | ||
function changeStatusDelegated(bool revoked, address namespace, bytes32 revocationList, bytes32 revocationKey) public; | ||
``` | ||
|
||
#### changeStatusDelegatedSigned ([see Meta Transactions](#MetaTransactions)) | ||
**OPTIONAL** implements a function to change the revocation status of a particular revocation key in a namespace's revocation list with a raw signature. | ||
```solidity | ||
function changeStatusDelegatedSigned(bool revoked, address namespace, bytes32 revocationList, bytes32 revocationKey, address signer, bytes calldata signature) public; | ||
``` | ||
|
||
#### changeStatusesInList | ||
**OPTIONAL** implements a function to change multiple revocation statuses in a namespace's revocation list at once. | ||
```solidity | ||
function changeStatusesInList(bool[] memory revoked, address namespace, bytes32 revocationList, bytes32[] memory revocationKeys) public; | ||
``` | ||
|
||
#### changeStatusesInListSigned ([see Meta Transactions](#MetaTransactions)) | ||
**OPTIONAL** implements a function to change multiple revocation statuses in a namespace's revocation list at once with a raw signature. | ||
```solidity | ||
function changeStatusesInListSigned(bool[] memory revoked, address namespace, bytes32 revocationList, bytes32[] memory revocationKeys, address signer, bytes calldata signature) public; | ||
``` | ||
|
||
#### changeStatusesInListDelegated | ||
**OPTIONAL** implements a function to change multiple revocation statuses in a namespace's revocation list at once by a revocation list's delegate. | ||
```solidity | ||
function changeStatusesInListDelegated(bool[] memory revoked, address namespace, bytes32 revocationList, bytes32[] memory revocationKeys) public; | ||
``` | ||
|
||
#### changeStatusesInListDelegatedSigned ([see Meta Transactions](#MetaTransactions)) | ||
**OPTIONAL** implements a function to change multiple revocation statuses in a namespace's revocation list at once with a raw signature generated by a revocation list's delegate. | ||
```solidity | ||
function changeStatusesInListDelegatedSigned(bool[] memory revoked, address namespace, bytes32 revocationList, bytes32[] memory revocationKeys, address signer, bytes calldata signature) public; | ||
``` | ||
|
||
### Revocation List Management | ||
|
||
#### | ||
**OPTIONAL** implements a function that returns the revocation status of a particular revocation list in a namespace. | ||
```solidity | ||
function listIsRevoked(address namespace, bytes32 revocationList) view public returns (bool); | ||
``` | ||
|
||
#### changeListStatus | ||
**OPTIONAL** implements a function to change the revocation of a revocation list itself. If a revocation list is revoked, all its keys are considered revoked as well. | ||
```solidity | ||
function changeListStatus(bool revoked, address namespace, bytes32 revocationList) public; | ||
``` | ||
|
||
#### changeListStatusSigned ([see Meta Transactions](#MetaTransactions)) | ||
**OPTIONAL** implements a function to change the revocation of a revocation list itself with a raw signature. If a revocation list is revoked, all its keys are considered revoked as well. | ||
```solidity | ||
function changeListStatusSigned(bool revoked, address namespace, bytes32 revocationList, address signer, bytes calldata signature) public; | ||
``` | ||
|
||
### Owner management | ||
|
||
#### changeListOwner | ||
**OPTIONAL** implement a function to change the revocation status of a revocation list. If a revocation list is revoked, all keys in it are considered revoked. | ||
```solidity | ||
function changeListOwner(address newOwner, address namespace, bytes32 revocationList) public; | ||
``` | ||
|
||
#### changeListOwnerSigned ([see Meta Transactions](#MetaTransactions)) | ||
**OPTIONAL** implement a function to change the revocation status of a revocation list with a raw signature. If a revocation list is revoked, all keys in it are considered revoked. | ||
```solidity | ||
function changeListOwnerSigned(address newOwner, address namespace, bytes32 revocationList, address signer, bytes calldata signature) public; | ||
``` | ||
|
||
### Delegation management | ||
|
||
#### addListDelegate | ||
**OPTIONAL** implements a function to add a delegate to an owner's revocation list in a namespace. | ||
```solidity | ||
function addListDelegate(address delegate, address namespace, bytes32 revocationList) public; | ||
``` | ||
|
||
#### addListDelegateSigned ([see Meta Transactions](#MetaTransactions)) | ||
**OPTIONAL** implements a function to add a delegate to an owner's revocation list in a namespace with a raw signature. | ||
```solidity | ||
function addListDelegateSigned(address delegate, address namespace, bytes32 revocationList, address signer, bytes calldata signature) public; | ||
``` | ||
|
||
#### removeListDelegate | ||
**OPTIONAL** implements a function to remove a delegate from an owner's revocation list in a namespace. | ||
```solidity | ||
function removeListDelegate(address delegate, address owner, bytes32 revocationList) public; | ||
``` | ||
|
||
#### removeListDelegateSigned ([see Meta Transactions](#MetaTransactions)) | ||
**OPTIONAL** implements a function to remove a delegate from an owner's revocation list in a namespace with a raw signature. | ||
```solidity | ||
function removeListDelegateSigned(address delegate, address namespace, bytes32 revocationList, address signer, bytes calldata signature) public; | ||
``` | ||
|
||
### Events | ||
|
||
#### RevocationStatusChanged | ||
**MUST** be emitted when `changeStatus`, `changeStatusSigned`, `changeStatusDelegated`, `changeStatusDelegatedSigned`, `changeStatusesInList`, `changeStatusesInListSigned`, `changeStatusesInListDelegated`, or `changeStatusesInListDelegatedSigned` was successfully executed. | ||
|
||
```solidity | ||
event RevocationStatusChanged( | ||
address indexed namespace, | ||
bytes32 indexed revocationList, | ||
bytes32 indexed revocationKey, | ||
bool revoked | ||
); | ||
``` | ||
|
||
#### RevocationListOwnerChanged | ||
**MUST** be emitted when `changeListOwner` or `changeListOwnerSigned` was successfully executed. | ||
|
||
```solidity | ||
event RevocationListOwnerChanged( | ||
address indexed namespace, | ||
bytes32 indexed revocationList, | ||
address indexed newOwner | ||
); | ||
``` | ||
|
||
#### RevocationListDelegateAdded | ||
**MUST** be emitted when `addListDelegate` or `addListDelegateSigned` was successfully executed. | ||
|
||
```solidity | ||
event RevocationListDelegateAdded( | ||
address indexed namespace, | ||
bytes32 indexed revocationList, | ||
address indexed delegate | ||
); | ||
``` | ||
|
||
#### RevocationListDelegateRemoved | ||
**MUST** be emitted when `removeListDelegate` or `removeListDelegateSigned` was successfully executed. | ||
|
||
```solidity | ||
event RevocationListDelegateRemoved( | ||
address indexed namespace, | ||
bytes32 indexed revocationList, | ||
address indexed delegate | ||
); | ||
``` | ||
|
||
#### RevocationListStatusChanged | ||
**MUST** be emitted when `changeListStatus` or `changeListStatusSigned` was successfully executed. | ||
|
||
```solidity | ||
event RevocationListStatusChanged( | ||
address indexed namespace, | ||
bytes32 indexed revocationlist, | ||
bool revoked | ||
); | ||
``` | ||
|
||
### Meta Transactions <span id="MetaTransactions"></span> | ||
|
||
This section uses the following terms: | ||
- **`transaction signer`**: An Ethereum address that signs arbitrary data for the contract to execute **BUT** does not commit the transaction. | ||
- **`transaction sender`**: An Ethereum address that takes signed data from a **transaction signer** and commits it wrapped with its own signature to the smart contract. | ||
|
||
An address (**transaction signer**) **MAY** be able to deliver a signed payload off-band to another address (**transaction sender**) that initiates the Ethereum interaction with the smart contract. The signed payload **MUST** be limited to be used only once ([Signed Hash](#SignedHash) + [nonces](#Nonce)). | ||
|
||
#### Signed Hash <span id="SignedHash"></span> | ||
|
||
The signature of the **transaction signer** **MUST** conform [EIP-712](./eip-712.md). This helps users understand what the payload they're signing consists of & it improves the protection against replay attacks. | ||
|
||
#### Nonce <span id="Nonce"></span> | ||
|
||
This EIP **RECOMMENDS** the use of a **dedicated nonce mapping** for meta transactions. If the signature of the **transaction sender** and its meta contents are verified, the contract increases a nonce for this **transaction signer**. This effectively removes the possibility for any other sender to execute the same transaction again with another wallet. | ||
|
||
## Rationale | ||
|
||
### Why the concept of namespaces? | ||
This provides every Ethereum address a reserved space, without the need to actively claim it in the contract. Initially addresses only have owner access in their own namespace. | ||
|
||
### Why does a namespace always represent the initial owner address? | ||
The change of an owner of a list shouldn't break the link to a revocation key in it, as already existing off-chain data may depend on it. | ||
|
||
## Backwards Compatibility | ||
No backward compatibility issues were found. | ||
|
||
## Security Considerations | ||
|
||
### Meta Transactions | ||
The signature of signed transactions could potentially be replayed on different chains or deployed versions of the registry implementing this ERC. This security consideration is addressed by the usage of [EIP-712](./eip-712.md) | ||
|
||
### Rights Management | ||
The different roles and their inherent permissions are meant to prevent changes from unauthorized entities. The revocation list owner should always be in complete control over its revocation list and who has writing access to it. | ||
|
||
## Copyright | ||
Copyright and related rights waived via [CC0](../LICENSE.md). |