How Aragon approaches identity and the Ethereum Keybase Resolver

Identity is one of the most important parts when developing decentralized applications. This is specially true for Aragon, where identity is needed to know who are you doing business with or who are the people that will manage the money you are investing.

Core values

When building identity into Aragon we settled for the following principles and we intend to maintain them in the future, no matter the scale of the project:

  • Identity is opt-in. Entities are free to transact anonymously (without their Ethereum address tied to any identity). For Aragon, this means our system needs to support the case where anonymous entities are creating and managing organizations.
  • Entities are free to choose how they want to identify themselves, and what identity providers do they consider valid to identify others. For us this means our identity system needs to be modular and extendible to adapt to different identity mechanisms.
  • Identity belongs to the individual (or organization). Not Google, not Facebook, and not even their government. This means the only entity that can provide the ultimate truth about their identity is themselves or entities they personally appoint for this (through cryptographic proofs).

Even though the premise of doing anonymous business if you want to seems cool, we know it is idealistic and there will be cases in which people will be socially required to prove their identity before some things can happen.

For example, an investor might require the founders to identify themselves before investing in a company or a payment provider might require to do traditional KYC before providing their service to the company.

Keybase

For Aragon we have built an integration with Keybase as our first identity provider.

As we have seen deciding on an identity system is matter of tradeoffs. Keybase has the downside of being a centralized service, and they could stop the service at any time and the integration would break.

But at the same time it is important that they are not the definitive source of truth, and everything they provide can be cryptographically checked and see that the user indeed provided that proof.

Verifying myself: I am vbuterin on Keybase.io. dXaAZIJCOhy_nxffjWFMn4v8-bBiL8YVod3E / https://t.co/bxwekt6mGK

January 12, 2017

Anyone wanting to check that my Keybase identity is the same than my Twitter profile can do so by checking my proof.

And the other important factor towards choosing Keybase as our first provider is that it is a somewhat mature solution with a good UX that can be used today. It also has some adoption in the broader tech and crypto community, so the barrier to entry is lower.

Keybase identity provider inside Aragon

That being said, and as our first and second identity principles state, it is not required to use nor have a Keybase account in order to use Aragon.

Integrating Keybase and Ethereum

When we started working on this problem, we came up with a quick solution and published an article about it.

Ethereum + Keybase registry proposal
https://hackernoon.com/ethereum-keybase-registry-proposal-c6497e3b2af7

This approach had two main problems:

  • It relied way too much on Oraclize and if Oraclize was corrupt it could undermine the whole system. We weren't comfortable at all by making a random third party the trusted party.
  • In order to have a 'trustless' two way verification (this username really owns this address) an onchain transaction to the registry was needed.
Keybase Registry 2.0

The most important change is the fact that in the new implementation the file that the user uploads to their KBFS is not a text file with the Ethereum address anymore, but a signed proof asserting that username owns an address, and cryptographically signed with that address private key.

In the case of Aragon, given that the main interface for users right now is a native desktop client, it allows us to find the username, sign the proof on behalf of the user and save the file to their KBFS directory, making the process very straight forward.

{
username:ji,
address:0xcc045ae84e5f3e12e150c418d7215a2b3863da20,
proofString:I am ji on Keybase verifying my Ethereum address 0xcc045ae84e5f3e12e150c418d7215a2b3863da20 by signing this proof with its private key,
signature:0x673ac837403b1fad2da56c7a4419afa6bd5c371b4903c7d848aad41e424e51a85f075e38f9a823a12d42312b1faf250c997babff2345bb6a1eab488ac84c79041b
}

https://ji.keybase.pub/ethereum_ropsten.json

The fact that this file exists in my KBFS public directory verifies that I own that username, and after fetching this proof anyone can verify the signature locally and independently, and prove that in fact it was signed with the address claimed.

This is a major improvement because there is no need for an on-chain component to perform searches username to address. Anyone can just get the file from my public KBFS https://.keybase.pub/ethereum.json and see if the address I’m claiming as mine is the one that signed that proof. If that is the case, nothing else is needed to be sure that a certain username owns an address private key and can sign with it.

The Keybase Registry on-chain component is still useful for having two way mappings between usernames and addresses. It still depends on Oraclize to function, but what it requests is the signature for a given username before creating the mapping. It performs the same check (ecrecover ) on-chain and if the proof is legit it creates the mapping.

The advantages of this new system is that anyone can verify anyone’s username on their behalf (and pay for the verification).

The API for getting information out of the contract is very straight forward:

contract KeybaseRegistryInterface {
// Lookup
function getAddress(string username) returns (address); // Lookup for an address given a username.
function getUsername(address ethAddress) returns (string username); // Reverse lookup of username for a given address
function myUsername() returns (string username); // Reverse lookup for sender

// Registering
function register(string username, address ethAddress) payable; // Starts registration for the provided address and username.
function registerSender(string username) payable; // Starts registration for tx sender for the provided username.
}

All the code for the registry is open source and you can check it out in the Github repository:

https://github.com/aragon/KeybaseRegistry

Bonus: ENS compatible Keybase Resolver

Given this new implementation, the need for having a on-chain registry is lower, but we figured out that an interesting use case of it would be to make it compatible with the Ethreum Name Service.

We built a very simple resolver that uses the Keybase Registry as its base class and provides the following mappings

ens.resolve(ji.keybase.eth) -> 0xcc...da20

ens.reverse(0xcc...da20.keybase.eth) -> ji

Once ENS launches in the mainnet, we will try to secure the keybase.eth name and deploy the resover there.

KeybaseRegistry/KeybaseResolver.sol
https://github.com/AragonOne/KeybaseRegistry/blob/master/contracts/KeybaseResolver.sol

Wrap up

We are very happy with our current integration with Keybase as it goes well with our principles on how identity should be built in Aragon.

We are of course looking forward to integrating other identity providers and allow users to freely decide what they want to use. We find uPort proposition very interesting and it is probably what we will be looking into next.