CAIP-122: Sign in With X (SIWx)
Author | Haardik, Sergey Ukustov |
---|---|
Discussions-To | https://github.com/ChainAgnostic/CAIPs/pull/122 |
Status | Review |
Type | Standard |
Created | 2022-06-23 |
Updated | 2022-07-06 |
Table of Contents
Abstract
Sign in With X describes how blockchain accounts should authenticate and authorize with off-chain services by signing a chain-agnostic message parameterized by scope, session details, and security mechanisms (e.g. a nonce).
The goal of this specification is to define a chain-agnostic data model. When accompanied with chain-specific message forms and signing algorithms, along with chain-agnostic serialization format, this would allow for a self-custodied alternative to centralized identity providers, and improve interoperability across off-chain services for blockchain-based authentication.
Motivation
As specified in EIP-4361, Sign in With Ethereum defined an Ethereum-focused workflow to authenticate Ethereum accounts on non-blockchain services. This work is meant to generalize and abstract the Sign in With Ethereum specification, thereby making EIP-4361 a specific implementation of this specification, to work with any cryptographic system’s namespace expressable in CAIP-10 and CAIP-2 formats.
Additionally, CAIP-74 specified a way to represent a chain-agnostic capability object (OCAP) by placing an EIP-4361 message into a CACAO container.
With this specification, we hope to extend CAIP-74 to support blockchains other than Ethereum and allow for the creation of Object Capabilities (OCAPs) in a chain-agnostic way.
Specification
Abstract Data Model
We start by declaring an abstract data model, which contains all the requisite information, metadata, and security mechanisms to authenticate and authorize with a blockchain account securely. We call this data model SIWX.
The data model MUST contain the following fields:
Name | Type | Mandatory | Description | |
---|---|---|---|---|
domain |
string | ✓ | RFC 4501 dnsauthority that is requesting the signing. |
|
account_address |
string | ✓ | Blockchain address performing the signing, expressed as the account_address segment of a CAIP-10 address; should NOT include CAIP-2 chain_id . |
namespace |
uri |
string | ✓ | RFC 3986 URI referring to the resource that is the subject of the signing i.e. the subject of the claim. | |
version |
string | ✓ | Current version of the message. | |
statement |
string | Human-readable ASCII assertion that the user will sign. It MUST NOT contain \n . |
||
nonce |
string | Randomized token to prevent signature replay attacks. | ||
issued-at |
string | RFC 3339 date-time that indicates the issuance time. |
||
expiration-time |
string | RFC 3339 date-time that indicates when the signed authentication message is no longer valid. |
||
not-before |
string | RFC 3339 date-time that indicates when the signed authentication message starts being valid. |
||
request-id |
string | System-specific identifier used to uniquely refer to the authentication request. | ||
chain_id |
string | ✓ | The chain_id segment of a CAIP-10, i.e., a CAIP-2 identifier for locating the address listed separately above. |
|
resources |
List of strings | List of information or references to information the user wishes to have resolved as part of the authentication by the relying party; express as RFC 3986 URIs and separated by \n . |
||
signature |
bytes | ✓ | Signature of the message signed by the wallet. | |
type |
string | ✓ | Type of the signature to be generated, as defined in the namespaces for this CAIP. |
Namespace Specification
A CAIP-104 namespace that enables SIWX for that namespace needs to define an implementation profile for this specification which MUST provide:
- a signing algorithm, or a finite set of these, where multiple different signing interfaces might be used,
- a
type
string(s) that designates each signing algorithm, for inclusion in thesignatureMeta.t
value of each signed response - a procedure for creating a signing input from the data model specified in this document for each signing algorithm
The signing algorithm MUST cover:
- how to sign the signing input,
- how to verify the signature.
Examples
As a general suggestion for authors and implementers, the signing input should be based on a string. The string should be human-readable, so that the signing represents the fully-informed consent of a user.
The proposed string representation format, adapted from EIP-4361, should be as such:
${domain} wants you to sign in with your **blockchain** account:
${account_address(address)}
${statement}
URI: ${uri}
Version: ${version}
Nonce: ${nonce}
Issued At: ${issued-at}
Expiration Time: ${expiration-time}
Not Before: ${not-before}
Request ID: ${request-id}
Chain ID: ${chain_id(address)}
Resources:
- ${resources[0]}
- ${resources[1]}
...
- ${resources[n]}
Here:
**blockchain**
represents a human-readable name of the ecosystem the user can recognize its account as belonging to,account_address(address)
is theaccount_address
segment of a CAIP-10address
of the data model,chain_id(address)
is achain_id
part of CAIP-10address
of the data model.
As an example, EIP-4361 directly conforms to this data model. Since EIP-155 chains can request personal signatures (EIP-191) or contract signatures (EIP-1271) in plaintext, an example message to be signed could be
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
Nonce: 32891756
Issued At: 2021-09-30T16:25:24Z
Chain ID: 1
Resources:
- ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/
- https://example.com/my-web2-claim.json
Other chains, however, for example Solana, cannot do plaintext signatures and require signing over raw bytes. As such, signing input for the data model could be created as a string, similar to EIP-4361 example above, that is represented as raw bytes. The signing input is then passed to Solana-specific signing algorithm. This should be defined in the Solana namespace for this CAIP specification.
Below is an example of the data model represented as a plain text similar Ethereum, and then converted to raw bytes.
Plain text representation:
service.org wants you to sign in with your Solana account:
GwAF45zjfyGzUbd3i3hXxzGeuchzEZXwpRYHZM5912F1
I accept the ServiceOrg Terms of Service: https://service.org/tos
URI: https://service.org/login
Version: 1
Nonce: 32891757
Issued At: 2021-09-30T16:25:24.000Z
Chain ID: 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d
Resources:
- ipfs://Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu
- https://example.com/my-web2-claim.json
Raw bytes (encoded as base64url for brevity).
c2VydmljZS5vcmcgd2FudHMgeW91IHRvIHNpZ24gaW4gd2l0aCB5b3VyIFNvbGFuYSBhY2NvdW50OgpHd0FGNDV6amZ5R3pVYmQzaTNoWHh6R2V1Y2h6RVpYd3BSWUhaTTU5MTJGMQoKSSBhY2NlcHQgdGhlIFNlcnZpY2VPcmcgVGVybXMgb2YgU2VydmljZTogaHR0cHM6Ly9zZXJ2aWNlLm9yZy90b3MKClVSSTogaHR0cHM6Ly9zZXJ2aWNlLm9yZy9sb2dpbgpWZXJzaW9uOiAxCk5vbmNlOiAzMjg5MTc1NwpJc3N1ZWQgQXQ6IDIwMjEtMDktMzBUMTY6MjU6MjQuMDAwWgpDaGFpbiBJRDogMQpSZXNvdXJjZXM6Ci0gaXBmczovL1FtZTdzczNBUlZneHY2clhxVlBpaWtNSjh1Mk5MZ21nc3pnMTNwWXJES0VvaXUKLSBodHRwczovL2V4YW1wbGUuY29tL215LXdlYjItY2xhaW0uanNvbg
Rationale
- As a chain-agnostic standard, SIWx should allow for authentication via blockchain wallet across non-blockchain applications regardless of which chain/wallet the user is using.
- The application server MUST be able to implement fully functional authentication for as many users as possible without forcing a change to wallets
- The model should be abstract enough to allow individual namespaces to represent the signing message as suitable for their chain, while allowing conformance with CAIP-74.
Backwards Compatibility
Not applicable.
Wallet Implementer Steps
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.invalid wants you to sign in..."
, the wallet checks that the request actually originated fromservice.invalid
. - The domain is expected to be read from a trusted data source such as the browser window.
References
- CAIP-2: Blockchain ID Specification
- CAIP-10: Account ID Specification
- CAIP-74: CACAO: Chain Agnostic CApability Object
- CAIP-104: Account ID Specification
- EIP-191: Signed Data Standard
- EIP-1271: Standard Signature Validation Method for Contracts
- EIP-4361: Sign-In with Ethereum
- RFC 4501: Domain Name System Uniform Resource Identifiers
- RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
- RFC 3339: Date and Time on the Internet: Timestamps
Copyright
Copyright and related rights waived via CC0.
Citation
Please cite this document as:
Haardik, Sergey Ukustov, "CAIP-122: Sign in With X (SIWx)," Chain Agnostic Improvement Proposals, no. 122, June 2022. [Online serial]. Available: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-122.md