--- eip: 1775 title: App Keys, application specific wallet accounts author: Vincent Eli (@Bunjin), Dan Finlay (@DanFinlay), Erik Marks (@rekmarks) discussions-to: https://ethereum-magicians.org/t/eip-erc-app-keys-application-specific-wallet-accounts/2742 status: Draft type: Standards Track category: ERC created: 2019-02-20 requires: 137 --- ## Simple Summary Among others cryptographic applications, scalability and privacy solutions for ethereum blockchain require that an user performs a significant amount of signing operations. It may also require her to watch some state and be ready to sign data automatically (e.g. sign a state or contest a withdraw). The way wallets currently implement accounts poses several obstacles to the development of a complete web3.0 experience both in terms of UX, security and privacy. This proposal describes a standard and api for a new type of wallet accounts that are derived specifically for a each given application. We propose to call them `app keys`. They allow to isolate the accounts used for each application, thus potentially increasing privacy. They also allow to give more control to the applications developers over account management and signing delegation. For these app keys, wallets can have a more permissive level of security (e.g. not requesting user's confirmation) while keeping main accounts secure. Finally wallets can also implement a different behavior such as allowing to sign transactions without broadcasting them. This new accounts type can allow to significantly improve UX and permit new designs for applications of the crypto permissionned web. ## Abstract In a wallet, an user often holds most of her funds in her main accounts. These accounts require a significant level of security and should not be delegated in any way, this significantly impacts the design of cryptographic applications if a user has to manually confirm every action. Also often an user uses the same accounts across apps, which is a privacy and potentially also a security issue. We introduce here a new account type, app keys, which permits signing delegation and accounts isolation across applications for privacy and security. In this EIP, we provide a proposal on how to uniquely identify and authenticate each application, how to derive a master account (or app key) unique for the domain from an user private key (her root private key or any other private key of an account derived or not from her root one). This EIP aims at becoming a standard on how to derive keys specific to each application that can be regenerated from scratch without further input from the user if she restores her wallet and uses again the application for which this key was derived. These app keys can then be endowed a different set of permissions (through the requestPermission model introduced in EIP [EIP2255](https://eips.ethereum.org/EIPS/eip-2255)). This will potentially allow an user to partly trust some apps to perform some crypto operations on their behalf without compromising any security with respect to her main accounts. ## Motivation Wallets developers have agreed on an HD derivation path for ethereum accounts using BIP32, BIP44, SLIP44, [(see the discussion here)](https://github.com/ethereum/EIPs/issues/84). Web3 wallets have implemented in a roughly similar way the rpc eth api. [EIP1102](https://eips.ethereum.org/EIPS/eip-1102) introduced privacy through non automatic opt-in of a wallet account into an app increasing privacy. However several limitations remain in order to allow for proper design and UX for crypto permissioned apps. Most of GUI based current wallets don't allow to: * being able to automatically and effortlessly use different keys / accounts for each apps, * being able to sign some app's action without prompting the user with the same level of security as sending funds from their main accounts, * being able to use throwable keys to improve anonymity, * effortlessly signing transactions for an app without broadcasting these while still being able to perform other transaction signing as usual from their main accounts, * All this while being fully restorable using the user's mnemonic or hardware wallet and the HD Path determined uniquely by the app's ens name. We try to overcome these limitations by introducing a new account's type, app keys, made to be used along side the existing main accounts. These new app keys can permit to give more power and flexibility to the crypto apps developers. This can allow to improve a lot the UX of crypto dapps and to create new designs that were not possible before leveraging the ability to create and handle many accounts, to presign messages and broadcast them later. These features were not compatible with the level of security we were requesting for main accounts that hold most of an user's funds. ## Specification ### Applications An app is a website (or other) that would like to request from a wallet to access a cryptographic key specifically derived for this usage. It can be any form of cryptography/identity relying application, Ethereum based but not only. Once connected to a wallet, an application can request to access an account derived exclusively for that application using the following algorithm. ### Private App Key generation algorithm We now propose an algorithm to generate keys specific to each application using only the user's master seed entropy, the BIP44 index of one of this user's accounts and the application unique identifier. This allows to generate application keys that: - are uniquely defined, with respect to the account that the user selected to generate these keys, - and thus can be isolated when changing the user account, allowing persona management (see next section), - are specific to each application, - can be fully restored from the user master seed mnemonic and the applications' names. #### Using different accounts as personas We allow the user to span a different set of application keys by changing the account selected to generate each key. Thus from the same master seed mnemonic, an user can use each of her account index to generate an alternative set of application keys. One can describe this as using different personas. This would allow potentially an user to fully isolate her interaction with a given app across personas. One can use this for instance to create a personal and business profile for a given's domain both backup up from the same mnemonic, using 2 different accounts to generate these. The app or domain, will not be aware that it is the same person and mnemonic behind both. If an application interacts with several main accounts of an user, one of these accounts, a master account can be used as persona and the others as auxiliary accounts. #### Applications' Unique Identifiers Each application is uniquely defined and authenticated by its name, a domain string. It can be a Domain Name Service (DNS) name or, in the future, an Ethereum Name Service (ENS) name or IPFS hash. There are a few restrictions however on the characters used and normalisation, each name should be passed through the [NamePrep Algorithm](https://tools.ietf.org/html/rfc3491) We recommend this standard to be following the [ENS Specs](http://docs.ens.domains/en/latest/implementers.html#namehash), reproduced below for convenience and reference. ``` Normalising and validating names Before a name can be converted to a node hash using Namehash, the name must first be normalised and checked for validity - for instance, converting fOO.eth into foo.eth, and prohibiting names containing forbidden characters such as underscores. It is crucial that all applications follow the same set of rules for normalisation and validation, as otherwise two users entering the same name on different systems may resolve the same human-readable name into two different ENS names. ``` #### Private App Key generation algorithm Using the domain name of an application, we generate a private key for each application (and per main account) : `const appKeyPrivKey = ethUtil.keccak(privKey + originString, 256)` where privKey is the private key of the user's account selected to span the application key and originString represents the origin url from which the permission call to access the application key is originated from. This is exposed as an RPC method to allow any domain to request its own app key associated with the current requested account (if available): ``` const appKey = await provider.send({ method: 'wallet_getAppKeyForAccount', params: [address1] }); ``` See here for an implementation: https://github.com/MetaMask/eth-simple-keyring/blob/master/index.js#L169 ## API: We propose to introduce new RPC methods but they should be restricted and wrapped such that some parameters (e.g. domain name) are imposed by the wallet on the caller depending on the caller's authentication. requestPermission can be extended in the future introducing new signing methods and more. ## Rationale ### Isolated paths but customisable The proposed specifications permit to have isolation between personas and between applications. Each persona / application combination will yield a unique subtree that can be explored by the application using the structure it would like to use. Personas are known only by the user and its wallet, application' UID based path is computable by everyone from the application's name. And then the application decides and communicates the final levels of the path. Only the wallet and the user will know the full tree and where we are in the tree (depth, parents). Applications will have knowledge only of the subtree, starting after the persona. ### Sharing application keys across domains: While this does not explicit cover cases of sharing these app keys between pages on its own, this need can be met by composition: Since a domain would get a unique key, and because domains can intercommunicate, one domain (app) could request another domain (signer) to perform its cryptographic operation on some data, with its appKey as a seed, potentially allowing new signing strategies to be added as easily as new websites. This could also pass it to domains that are loading specific signing strategies. This may sound dangerous at first, but if a domain represents a static hash of a trusted cryptographic function implementation, it could be as safe as calling any audited internal dependency. ### Privacy and the funding trail If all an application needs to do with its keys is to sign messages and it does not require funding, then this EIP allows for privacy through the use of distinct keys for each application with a simple deterministic standard compatible across wallets. However if these application keys require funding, there can be trail and the use of app keys would not fully solve the privacy problem there. Mixers or anonymous ways of funding an ethereum address (ring signatures) along with this proposal would guarantee privacy. Even if privacy is not solved fully without this anonymous funding method, we still need a way to easily create and restore different accounts/addresses for each application ## Backwards Compatibility From a wallet point of view, there does not seem to be compatibility issues since these are separate accounts from those that were used previously by wallets and they are supposed to be used along-side in synergy. However, for applications that associated in some way their users to their main accounts may want to reflect on if and how they would like to leverage the power offered by `app keys` to migrate to them and leverage on the new app designs they permit. ## Implementation Here is an early implementation of app keys for standard (non HW) MetaMask accounts. https://github.com/MetaMask/eth-simple-keyring/blob/6d12bd9d73adcccbe0b0c7e32a99d279085e2934/index.js#L139-L152 See here for a fork of metamask that implements app keys along side plugins: https://github.com/MetaMask/metamask-snaps-beta https://github.com/MetaMask/metamask-snaps-beta/wiki/Plugin-API ## Example use cases * signing transactions without broadcasting them https://github.com/MetaMask/metamask-extension/issues/3475 * token contract https://github.com/ethereum/EIPs/issues/85 * default account for dapps https://ethereum-magicians.org/t/default-accounts-for-dapps/904 * non wallet/crypto accounts [EIP1581: Non-wallet usage of keys derived from BIP32 trees](https://eips.ethereum.org/EIPS/eip-1581) * state channel application * privacy solution * non custodian cross cryptocurrency exchange... ## Acknowledgements MetaMask team, Christian Lundkvist, Counterfactual team, Liam Horne, Erik Bryn, Richard Moore, Jeff Coleman. ## References ### HD and mnemonics #### BIPs * [BIP32: Hierarchical Deterministic Wallets:](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) * [BIP39: Mnemonic code for generating deterministic keys:](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) * [SLIP44: Registered coin types for BIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) #### Derivation path for eth * [Issue 84](https://github.com/ethereum/EIPs/issues/84) * [Issue 85](https://github.com/ethereum/EIPs/issues/85) * [EIP600 Ethereum purpose allocation for Deterministic Wallets](https://eips.ethereum.org/EIPS/eip-600) * [EIP601 Ethereum hierarchy for deterministic wallets](https://eips.ethereum.org/EIPS/eip-601) ### Previous proposals and discussions related to app keys * [Meta: we should value privacy more](https://ethereum-magicians.org/t/meta-we-should-value-privacy-more/2475) * [EIP1102: Opt-in account exposure](https://eips.ethereum.org/EIPS/eip-1102) * [EIP1581: Non-wallet usage of keys derived from BIP-32 trees](https://eips.ethereum.org/EIPS/eip-1581) * [EIP1581: discussion](https://ethereum-magicians.org/t/non-wallet-usage-of-keys-derived-from-bip-32-trees/1817/4) * [SLIP13: Authentication using deterministic hierarchy](https://github.com/satoshilabs/slips/blob/master/slip-0013.md) ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).