Extending Sign-In with Ethereum to Authorizations - ReCap

Sign-In with Ethereum describes how Ethereum accounts authenticate with off-chain applications. ReCap introduces a mechanism that allows an off-chain application to combine authentication and authorization of such, while preserving security and optimizing UX.

Extending Sign-In with Ethereum to Authorizations - ReCap

Sign-In with Ethereum (SIWE) describes how Ethereum accounts authenticate with off-chain applications by signing a standard message format. While SIWE focuses on user log-in, there is no canonical way to interact with an additional service on behalf of the authenticated Ethereum account, such as one that enables a user to bring their own data to a session.

ReCap (EIP-5573) allows an off-chain application to combine authentication and authorization while preserving security and optimizing for UX.

With ReCap, an off-chain application can ask the user to authenticate using SIWE (EIP-4361) while also allowing the user to authorize the application to access third-party resources for that session–all with a single wallet interaction. Because ReCap enforces informed consent, the wallet will always show the users exactly what permissions would be granted.

A ReCap is a valid EIP-4361 message that follows additional structure defined in EIP-5573, allowing an Ethereum account to delegate a set of capabilities (ReCaps) to a delegate through informed user consent. SIWE ReCap implements an object-capability (ocap) model using Ethereum-native signature algorithms and data models.

Through an extension mechanism, it can be combined with other ocap-like models as well such as a UCAN or ZCap-LD. EIP-5573 is fully compatible with EIP-4361 which ensures that existing SIWE-enabled applications won’t break.

Each resource service can define its own ReCap namespace which describes actions that can be executed on resources that exist within the namespace. Examples include but are not limited to creating, updating, or deleting certain resources, such as a blog post or key-value store entry. There is no limitation on what semantics a resource service might define for their given namespace since ReCap has a flexible extensibility mechanism built in.

Using Sign-In with Ethereum with ReCaps

Adding ReCaps to SIWE does not require major changes. The key difference is that the application encodes additional capabilities in the SIWE message, allowing the user to delegate permissions to the application for a limited period of time and under certain conditions (such as enforcing revocation checks or holder bindings).

After the application receives the signed ReCap from the user’s wallet, it may access the specified actions and resources on behalf of the user. This can only be done while the ReCap has not expired or been revoked. Revocation is out-of-scope of ReCap but can be implemented by the resource service on top of ReCaps. The following diagram illustrates a common ReCap usage pattern where the user gives informed consent to an application to allow the application to manage data on their behalf that resides in a third-party self-sovereign storage resource service:

Resource services need to authenticate that the application is indeed the valid delegate of the Ethereum account. Merely possessing a signed ReCap does not constitute authentication, as would be in the case of a bearer token. Instead, ReCaps are bound to a specific party ("holder binding"). The application can perform authentication for the resource service by signing a message with a delegated key as described our post on session keys, but resource services are free to define their own mechanism in their API.

From Sign-In with Ethereum to Session Keys
Session keys let users root all their digital interactions to their keys.

Adding SIWE ReCap to Your Application

Applications can use ReCaps to access user-controlled resource services by:

  • Adding ReCap URIs to the SIWE Resources array.
  • Appending the deterministic text to the SIWE statement field.

This will ensure the user can be presented with a correct and human-readable summary of the granted permissions for purposes of ensuring informed consent through SIWE ReCap.

Resource services can serve protected resources through SIWE ReCaps by:

  • Defining the namespace for their resource service.
  • Defining the possible actions per resource or for all resources the user may authorize.
  • If applicable, defining the resources that can be targeted in ReCaps and how they are identified in the namespace.
  • Verifying the signed SIWE ReCap and validating that the delegate was authorized to execute the actions on behalf of an Ethereum Account.
  • Verifying the requester is the designated delegate of the SIWE ReCap.
example.com wants you to sign in with your Ethereum account:
0x0000000000000000000000000000000000000000

I further authorize https://example.com to perform
the following actions on my behalf: (1) example: read
for any. (2) example: append, delete for my.resource.1.
(3) example: append for my.resource.2, my.resource.3.

URI: https://example.com
Version: 1
Chain ID: 1
Nonce: n0S6WzA2Mj
Issued At: 2022-06-21T12:00:00.000Z
Resources:
- urn:recap:example:eyJkZWYiOlsicmVhZCJdLCJ0YXIiOnsibXkucm
Vzb3VyY2UuMSI6WyJhcHBlbmQiLCJkZWxldGUiXSwibXkucmVzb3VyY2U
uMiI6WyJhcHBlbmQiXSwibXkucmVzb3VyY2UuMyI6WyJhcHBlbmQiXX19

Let’s break down what the example above means.

Each ReCap is represented by an entry in the Resources array of the SIWE message encoded as a ReCap URI that deterministically translates the ReCap in human-readable form to the statement field in the SIWE message using the ReCap Translation Algorithm (as defined in EIP-5573). This ensures that the user has an opportunity to read and understand what they are signing even without additional support from Ethereum wallets. It also ensures cryptographic integrity of the informed consent and prevents applications from diluting the attenuation after the user signed the message.

ReCap URIs are self-contained URIs with an embedded ReCap Capability encoded as a base64url-encoded JSON Object that follow a simple URI scheme:

urn:recap:<namespace>:<capability-object>

A ReCap URI starts with urn:recap: followed by the namespace chosen by the resource service, e.g., example, and followed by the ReCap Capability Object which describes which actions the user grants to the application. These actions can be defined by the resource service and selectively granted to the application. The following is the decoded ReCap Capability Object from the example above:

{
    "def":[
      "read"
    ],
    "tar":{
      "my.resource.1":[
      	"append",
        "delete"
    ],
      "my.resource.2":[
      	"append"
    ],
      "my.resource.3":[
        "append"
    ]
  }
}

In our example, the resource service decided to expose an API to allow users to delegate two different actions to applications: append and delete, under the namespace example. Actions can be either targeted or untargeted. While targeted actions are associated with resources defined in the ReCap Capability Object, untargeted actions are not tied to a particular resource.

To obtain informed consent from the user, SIWE messages with the ReCap extension must append deterministically-generated text derived from the ReCap URIs in the Resources array to the statement field. In our example above, the following represents this text:

I further authorize https://example.com to perform the following actions on my behalf: (1) example: read for any. (2) example: append, delete for my.resource.1. (3) example: append for my.resource.2, my.resource.3.

It is important to note that the user-controlled resource service, and not the application, must define the deterministic generation function outputting the text that the user will ultimately sign. This ensures that a malicious application cannot construct a nefarious message to fool the user into delegating different access than intended. Longer-term, we imagine wallets can add support to further interpreting these messages into more ergonomic UX, just as many are now providing fully-fledged "sign-in" dialogs for SIWE as opposed to unadorned personal sign requests.

Attenuation

Attenuation is the winnowing of permissions towards the principle of least privilege, and in ReCaps it's applied across two layers.

The first layer is the SIWE message containing attenuations affecting all ReCaps in the Resources section, and the second layer is the ReCap Capability Object itself. The ReCap Capability Object can only make the previous attenuations stricter or provide additional context information required by the resource service.

Certain SIWE message fields are used to further attenuate the scope of the delegation. Most importantly, the URI field in the SIWE message defines the delegate of the Ethereum account. Since it is a URI it can be a website (e.g., https://example.com), a public key (e.g., did:key:z6Mk…), an ENS name (e.g., did:ens:alice.eth) or anything else that can be identified by a URI.

Other SIWE message fields to attenuate include limiting the validity period of the ReCap Capability through Issued At, Expiration Time , and Not Before.

Getting Involved

SIWE ReCap is a proposed Ethereum Improvement Proposal (EIP).

Add EIP-5573: SIWE ReCap Extension by awoie · Pull Request #5573 · ethereum/EIPs
When opening a pull request to submit a new EIP, please use the suggested template: https://github.com/ethereum/EIPs/blob/master/eip-template.md We have a GitHub bot that automatically merges some ...

To get involved in the discussion on the EIP itself, check out the EIP-5573 thread on Ethereum Magicians, or join our Discord. If you are interested in building on SIWE ReCaps, you can check out our Open Source implementation.

GitHub - spruceid/siwe-recap: Capabilities for humans to read. Build wallet-signable messages with capability delegations that are human- and machine-readable.
Capabilities for humans to read. Build wallet-signable messages with capability delegations that are human- and machine-readable. - GitHub - spruceid/siwe-recap: Capabilities for humans to read. Bu...

Spruce lets users control their data across the web. If you're curious about integrating Spruce's technology into your project, come chat with us in our Discord: