owned this note
owned this note
Published
Linked with GitHub
# Sign-In with Ethereum
```
---
eip: 4361
title: Sign-In with Ethereum.
description: Standardizes off-chain authentication for Ethereum accounts to establish sessions.
author: Wayne Chang (@wyc), Brantly Millegan (@brantlymillegan), Nick Johnson (@Arachnid)
resolution: <TBD>
discussions-to: https://github.com/ethereum/EIPs/pull/4361
status: Draft
type: Standards Track
category: ERC
created: 2021-10-11
requires: EIP-55, EIP-191, EIP-137, EIP-155, EIP-1271, EIP-1328
---
```
## Abstract
*Abstract is a multi-sentence (short paragraph) technical summary. This should be a very terse and human-readable version of the specification section. Someone should be able to read only the abstract to get the gist of what this specification does.*
Sign-In with Ethereum describes how Ethereum accounts authenticate with off-chain services by signing a standard message format parameterized by scope, session details, and security mechanisms (e.g., a nonce). The goals of this specification are to provide a self-custodied alternative to centralized identity providers, improve interoperability across off-chain services for Ethereum-based authentication, and provide wallet vendors a consistent machine-readable message format to achieve improved user experiences and consent management.
## Motivation
*A motivation section is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright.*
When signing in to popular non-blockchain services today, users will typically use identity providers (IdPs) that are centralized entities with ultimate control over users' identifiers, for example, large internet companies and email providers. Incentives are often misaligned between these parties. Sign-In with Ethereum offers a new self-custodial option for users who wish to assume more control and responsibility over their own digital identity.
Already, many services support workflows to authenticate Ethereum accounts using message signing, such as to establish a cookie-based web session which can manage privileged metadata about the authenticating address. This is an opportunity to standardize the sign-in workflow and improve interoperability across existing services, while also providing wallet vendors a reliable method to identify signing requests as Sign-In requests for improved UX.
This work is sponsored by the Ethereum Foundation and Ethereum Name Service (ENS). It is being developed in the open through a series of recorded community calls and public repositories, and its development is informed by over twenty user interviews with a focus on currently-in-production uses, related prior EIPs, and fits within product roadmaps.
## Specification
*The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumJ, ethereumjs-lib, and others.*
Sign-In with Ethereum works as follows:
1. The wallet presents the user with a structured plaintext message or equivalent interface for signing with the EIP-191 signature scheme (string prefixed with `\x19Ethereum Signed Message:\n<length of message>`). The `message` MUST incorporate an Ethereum `address`, `version` of the message, `uri` for scoping, `nonce` acceptable to the server, and `issued-at` timestamp.
2. The signature is then presented to the server, which checks the signature's validity and message content.
3. Additional fields, including `expiration-time`, `not-before`, `request-id`, `chain-id`, and `resources` may be incorporated as part of authentication for the session.
4. The server may further fetch data associated with the Ethereum address, such as from the Ethereum blockchain (e.g., ENS, account balances, ERC-20/ERC-721/ERC-1155 asset ownership), or other data sources that may or may not be permissioned.
### Example message to be signed
```
service.org wants you to sign in with your Ethereum account:
0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
I accept the ServiceOrg Terms of Service: https://service.org/tos
URI: https://service.org/login
Version: 1
Chain ID: 1
Nonce: 328917
Issued At: 2021-09-30T16:25:24Z
Resources:
- ipfs://Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu
- https://example.com/my-web2-claim.json
```
### Informal Message Template
A Bash-like informal template of the full message is presented below for readability and ease of understanding. Field descriptions are provided in the following section. A full ABNF description is provided in the section thereafter.
```
${domain} wants you to sign in with your Ethereum account:
${address}
${statement}
URI: ${uri}
Version: ${version}
Chain ID: ${chain-id}
Nonce: ${nonce}
Issued At: ${issued-at}
Expiration Time: ${expiration-time}
Not Before: ${not-before}
Request ID: ${request-id}
Resources:
- ${resources[0]}
- ${resources[1]}
...
- ${resources[n]}
```
### Message Field Descriptions
- `domain` is the RFC 4501 `dnsauthority` that is requesting the signing.
- `address` is the Ethereum address performing the signing conformant to capitalization encoded checksum specified in EIP-55 where applicable.
- `statement` (optional) is a human-readable ASCII assertion that the user will sign, and it must not contain `'\n'`.
- `uri` is an RFC 3986 URI referring to the resource that is the subject of the signing (as in the _subject of a claim_).
- `version` is the current version of the `message`, which MUST be `1` for this specification.
- `chain-id` is the EIP-155 Chain ID to which the session is bound, and the network where Contract Accounts must be resolved.
- `nonce` is a randomized token used to prevent replay attacks, at least 8 alphanumeric characters.
- `issued-at` is the ISO 8601 datetime string of the current time.
- `expiration-time` (optional) is the ISO 8601 datetime string that, if present, indicates when the signed authentication message is no longer valid.
- `not-before` (optional) is the ISO 8601 datetime string that, if present, indicates when the signed authentication message will become valid.
- `request-id` (optional) is an system-specific identifier that may be used to uniquely refer to the sign-in request.
- `resources` (optional) is a list of information or references to information the user wishes to have resolved as part of authentication by the relying party. They are expressed as RFC 3986 URIs separated by `"\n- "`.
### ABNF Message Format
The `message` to be signed MUST conform with the following Augmented Backus–Naur Form (ABNF, RFC 5234) expression (note that `%s` denotes case sensitivity for a string term, as per RFC 7405).
```abnf
sign-in-with-ethereum =
domain %s"wants you to sign in with your Ethereum account:" LF
address LF
LF
[ statement LF ]
LF
%s"URI: " url LF
%s"Version: " version LF
%s"Nonce: " nonce LF
%s"Issued At: " issued-at LF
[ %s"Expiration Time: " expiration-time LF ]
[ %s"Not Before: " not-before LF ]
[ %s"Request ID: " request-id LF ]
[ %s"Chain ID: " chain-id LF ]
[ %s"Resources:" LF
resources ]
domain = dnsauthority
; From RFC 4501:
; dnsauthority = host [ ":" port ]
; See RFC 4501 for the fully contextualized
; definition of "dnsauthority".
address = "0x" 40*40HEXDIG
; Must also conform to captilization
; checksum encoding specified in EIP-55
; where applicable (EOAs).
statement = *( reserved / unreserved )
; See RFC 3986 for the definition
; of "reserved" and "unreserved".
; The purpose is to exclude LF ('\n').
uri = URI
; See RFC 3986 for the definition of "URI".
version = "1"
nonce = 8*( ALPHA / DIGIT )
; See RFC 5234 for the definition
; of "ALPHA" and "DIGIT".
issued-at = date-time
expiration-time = date-time
not-before = date-time
; See RFC 3339 for the
; definition of "date-time".
request-id = *pchar
; See RFC 3986 for the definition of "pchar".
chain-id = 1*DIGIT
; See EIP-155 for valid CHAIN_IDs.
resources = resource *( LF resource )
resource = "- " URI
```
#### Signing and Verifying with Ethereum Accounts
- For Externally Owned Accounts (EOAs), the verification method specified in EIP-191 MUST be used.
- For Contract Accounts,
- The verification method specified in EIP-1271 MUST be used.
- When performing EIP-1271 signature verification, the contract performing the verification MUST be resolved from the specified `chain-id`.
- Implementers SHOULD take into consideration that EIP-1271 implementations are not required to be pure functions, and can return different results for the same inputs depending on blockchain state. This can affect the security model and session validation rules. For example, a service with EIP-1271 signing enabled may rely on webhooks to receive notifications when state affecting the results is changed. When it receives a notification, it invalidates any matching sessions.
### Resolving Ethereum Name Service (ENS) Data
- The server or wallet MAY additionally perform resolution of ENS data, as this can improve the user experience by displaying a human-friendly information that is related to the `address`. Resolvable ENS data include:
- The [primary ENS name](https://docs.ens.domains/dapp-developer-guide/resolving-names#reverse-resolution).
- The [ENS avatar](https://gist.github.com/Arachnid/9db60bd75277969ee1689c8742b75182).
- Any other resolvable resources specified in [the documentation](https://docs.ens.domains/dapp-developer-guide/resolving-names#looking-up-other-resources).
- If resolution of ENS data is performed, implementers SHOULD take precautions to preserve user privacy and consent, as their `address` could be forwarded to third party services as part of the resolution process.
### Server-Side (Relying Party) Implementer Guidelines
#### Verifying a signed `message`
- The message MUST be checked for conformance to the ABNF above, checked against expected term values after parsing, and its signature must be verified.
#### Creating sessions
- Sessions MUST be bound to the `address` and not to further resolved resources that may change.
#### Interpreting and resolving `resources`
- The listed `resources` must be RFC 3986 URIs, but their interpretation is out of scope of this specification.
- Implementers SHOULD ensure that that URIs are human-friendly when expressed in plaintext form.
### Wallet Implementer Guidelines
#### Verifying `message`
- The full `message` MUST be checked for conformance to the ABNF above.
#### Verifying `domain` binding
- Wallet implementers MUST prevent phishing attacks by matching on the `domain` term when processing a signing request. For example, when processing the message beginning with `"service.org wants you to sign in..."`, the wallet checks that the request actually originated from `service.org`.
- The domain SHOULD be read from a trusted data source such as the browser window or over WalletConnect (EIP-1328) sessions for comparison against the signing message contents.
#### Creating Sign-In with Ethereum interfaces
- Wallet implementers MUST display to the user the following terms from the Sign-In with Ethereum signing request by default and prior to signing: `domain`, `address`, `statement`, and `resources`. Other terms MUST also be made available to the user prior to signing either by default or through an extended interface.
- Wallet implementers displaying a plaintext `message` to the user SHOULD require the user to scroll to the bottom of the text area prior to signing.
- Wallet implementers MAY construct a custom Sign-In With Ethereum user interface by parsing the ABNF terms into data elements for use in the interface. The display rules above still apply to custom interfaces.
#### Supporting internationalization (i18n)
- After successfully parsing the message into ABNF terms, translation may happen at the UX level per human language.
## Rationale
*The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.*
### Requirements
From the [RFP](https://notes.ethereum.org/@djrtwo/sign-in-with-ethereum-RFP):
> Write a specification for how Sign-In with Ethereum should work, both with and without Oauth. Include best practices and recommended graphics. The specification should be simple and generally follow existing practices. Avoid feature bloat, particularly the inclusion of lesser-used projects who see getting into the specification as a means of gaining adoption. The core specification should be decentralized, open, non-proprietary, and have long-term viability. It should have no dependence on a centralized server except for the servers already being run by the application that the user is signing in to. The basic specification should include: Ethereum accounts used for authentication, ENS names for usernames (via reverse resolution), and data from the ENS name’s text records for additional profile information (e.g. avatar, social media handles, etc).
Additional requirements added by authors:
1. The user must be presented a human-understandable interface prior to signing, mostly free of machine-targeted artifacts such as JSON blobs, hex codes (aside from the Ethereum address), and baseXX-encoded strings.
2. The application server must be able to implement fully usable support for its end without forcing a change in the wallets.
3. There must be a simple and straightforward upgrade path for both applications and wallets already using Ethereum account-based signing for authentication.
4. There must be facilities and guidelines for adequate mitigation of Man-in-the-Middle (MITM) attacks, replay attacks, and malicious signing requests.
### Design Goals
1. Human-Friendly
2. Simple to Implement
3. Secure
4. Machine Readable
5. Extensible
### Technical Decisions
- Why EIP-191 (Signed Data Standard) over EIP-712 (Ethereum typed structured data hashing and signing)
- EIP-191 is already broadly supported across wallets, while EIP-712 support is pending. **(1, 2, 3, 4)**
- https://github.com/LedgerHQ/app-ethereum/issues/105
- https://github.com/trezor/trezor-firmware/pull/1568
- EIP-191 is simple to implement using a pre-set prefix prior to signing, while EIP-712 is more complex to implement requiring the further implementations of a bespoke Solidity-inspired type system, RLP-based encoding format, and custom keccak-based hashing scheme. **(2)**
- EIP-191 produces more human-readable messages, while EIP-712 creates signing outputs for machine consumption, with most wallets not displaying the payload to be signed in a manner friendly to humans. **(1)**![](https://i.imgur.com/yvhz2mD.png)
- EIP-712 has the advantage of on-chain representation and on-chain verifiability, such as for their use in metatransactions, but this feature is not relevant for the specification's scope. **(2)**
- Why not use JWTs? Wallets don't support JWTs. The keccak hash function is [not assigned by IANA](https://www.iana.org/assignments/jose/jose.xhtml) for use as a JOSE algorithm. **(2, 3)**
- Why not use YAML or YAML with exceptions? YAML is loose compared to ABNF, which can readily express character set limiting, required ordering, and strict whitespacing. **(2, 3)**
- Why is Chain ID optional? Implementers have use cases that require cross-EVM/all-EVM functionality. Omission of Chain ID is the way to express this intent. **(1, 2, 5)**
### Discussions and Acknowledgements
- @awoie and @rh7 led the discussion on EIP-712 and EIP-191 signing schemes, including the benefits of structured data types and potential for extensions when using EIP-712.
- @awoie surfaced a number of privacy and security considerations related to MITM attacks, replay attacks, relay attacks, and RP-binding.
- @pedrouid suggested a YAML-inspired message format that struck the balance between human and machine readable.
- @Amxx suggested adding the `version` indicator to allow forwards-compatibility, and also brought up important implications between EIP-1271 and network selection.
- @mhluongo led discussion around i18n support and suggesting several improvements around the message format.
- @oed suggested low-impact changes that could do a lot to enable capabilities-based permissioning models.
- @kdenhartog brought up several OIDC models of identity, and examples of using EIP-712 to structure data.
- @cfelde suggested a minor improvement to the ABNF grammar.
## Backwards Compatibility
*All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright.*
- Most wallet implementations already support EIP-191, so this is used as a base pattern with additional features.
- Requirements were gathered from existing implementations of similar sign-in workflows, including statements to allow the user to accept a Terms of Service, nonces for replay protection, and inclusion of the Ethereum address itself in the message.
## Forwards Compatibility
- DIDs/VCs/Cross-Chain?
- SIOPv2?
- EIP-712? Which version?
- Version interpretation rules, e.g., sign with minor revision greater than understood, but not greater major version.
## Test Cases
*Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Tests should either be inlined in the EIP as data (such as input/expected output pairs, or included in ../assets/eip-###/<filename>.*
WIP
## Reference Implementation
**An optional section that contains a reference/example implementation that people can use to assist in understanding or implementing this specification.**
WIP
## Security Considerations
*All EIPs must contain a section that discusses the security implications/considerations relevant to the proposed change. Include information that might be important for security discussions, surfaces risks and can be used throughout the life-cycle of the proposal. E.g. include security-relevant design decisions, concerns, important discussions, implementation-specific guidance and pitfalls, an outline of threats and risks and how they are being addressed. EIP submissions missing the “Security Considerations” section will be rejected. An EIP cannot proceed to status “Final” without a Security Considerations discussion deemed sufficient by the reviewers.*
#### Identifier reuse
- Towards perfect privacy, it would be ideal to use a new uncorrelated identifier (e.g., Ethereum address) per digital interaction, selectively disclosing the information required and no more.
- This concern is less relevant to certain user demographics who are likely to be early adopters of this specification, such as those who manage an Ethereum address and/or ENS names intentionally associated with their public presence. These users often prefer identifier reuse to maintain a single correlated identity across many services.
- This consideration will become increasingly important with mainstream adoption. There are several ways to move towards this model, such as using HD wallets, signed delegations, and zero-knowledge proofs. However, these approaches are out of scope for this specification and better suited for follow-on specifications.
#### Key management
- Sign-In with Ethereum gives users control through their keys. This is additional responsiblity that mainstream users may not be accustomed to accepting, and key management is a hard problem especially for individuals. For example, there is no "forgot password" button as centralized identity providers commonly implement.
- Early adopters of this specification are likely to be already adept at key management, so this consideration becomes more relevant with mainstream adoption.
- Certain wallets can use smart contracts and multisigs to provide an enhanced user experiences with respect to key usage and key recovery, and these can be supported via EIP-1271 signing.
#### Minimizing wallet and server interaction
- In some implementions of wallet sign-in workflows, the server first sends parameters of the `message` to the wallet. Others generate the message for signing entirely in the client side (e.g., dapps). The latter approach without initial server interaction SHOULD be preferred when there is a user privacy advantage by minimizing wallet-server interaction. Often, the backend server first produces a `nonce` to prevent replay attacks, which it verifies after signing. Privacy-preserving alternatives are suggested in the next section on preventing replay attacks.
- Before the wallet presents the message signing request to the user, it MAY consult the server for the proper contents of the message to be signed, such as an acceptable `nonce` or requested set of `resources`. When communicating to the server, the wallet SHOULD take precautions to protect user privacy by mitigating user information revealed as much as possible.
- Prior to signing, the wallet MAY consult the user for preferences, such as the selection of one `address` out of many, or a preferred ENS name out of many.
#### Preventing replay attacks
- A `nonce` should be selected per session initiation with enough entropy to prevent replay attacks, a man-in-the-middle attack in which an attacker is able to capture the user's signature and resend it to establish a new session for themselves.
- Implementers MAY consider using privacy-preserving yet widely-available `nonce` values, such as one derived from a recent Ethereum block hash or a recent Unix timestamp.
#### Verification of domain binding
- Wallets MUST check that the `domain` matches the the actual signing request source.
- This value SHOULD be checked against a trusted data source such as the browser window or over WalletConnect (EIP-1328).
#### Channel security
- For web-based applications, all communications SHOULD use HTTPS to prevent man-in-the-middle attacks on the message signing.
- When using protocols other than HTTPS, all communications SHOULD be protected with proper techniques to maintain confidentiality, data integrity, and sender/receiver authenticity.
#### Session invalidation
There are several cases where an implementer SHOULD check for state changes as they relate to sessions.
- If an EIP-1271 implementation or dependent data changes the signature computation, the server SHOULD invalidate sessions appropriately.
- If any resources specified in `resources` change, the server SHOULD invalidate sessions appropriately. However, the interpretation of `resources` is out of scope of this specification.
#### Maximum lengths for ABNF terms
- While this specification does not contain normative requirements around maximimum string lengths, implementers SHOULD choose maximum lengths for terms that strike a balance across the prevention of denial of service attacks, support for arbitrary use cases, and user readability.
## Copyright Waiver
*All EIPs must be in the public domain. See the bottom of this EIP for an example copyright waiver.*
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).