Our research at MetaMask has lead us to propose the following EIP and we would very much appreciate if the community gave us feedback such that we can come to an agreement on a standard that would be appropriate both for wallets and applications developers to guarantee cross-compatibility.
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 increasing privacy. They also allow to give more control to the applications developpers 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.
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 how to uniquely identify and authenticate each application, how to derive the accounts along an Hierachical Deterministic (HD) path restricted for the domain and we finally define an API for applications to derive and use these app keys. This ERC aims at finding a standard that will fit the needs of wallets and application developers while also allowing app keys to be used across wallets and yield the same accounts for the user for each application.
Elements to discuss:
The motivation of this ERC is to get feedback about the following points:
Eventually this proposal could be extended to support other cryptographic curves, facilitating alternative cryptography like zk-STARKs.
While this proposal generates a path for key generation per domain, a delegation system could allow groups of distinct domains to coordinate securely.
To revoke these keys the client will need to keep track of the revoked keys, and skip them when generating keys in the future. This is an important requirement of any wallet implementing this standard (personal side-chains, anyone?).
There is 3 proposals in there. The two on signature are similar to appkey in intent but use the main account (no isolation) and is restricted to EIP712 signature in its current form. it allows them to be used without modification, except for an extra domain Seperator field in EIP712.
The one on encryption could be applied to app keys.
In that article, it is also mentioned the idea of smart contract domain approval by users. This would allow users to stay in control of which domain has the right to act on behalf of the users on each smart contract following the standard. For app keys I guess this can be done via address. Any plan to standardise such in this proposal?
This one (modified in this direction by @pedrouid) could also be used for app keys to let wallet.appkey.enable return an authenticated account by passing a challenge to the request, instead of having the application to do a signature request on top.
As for general comments, I ll have a closer read later, but few things jumped to mind :
the option to use app keys per content hash is I think very important for fully decentralised app where even the app creator and ENS name owner should be considered malicious. Relying on the ENS is prone to vulnerability as you mentioned. ENS should be used for discoverability not as the basis for security. As such app key should ideally be using the contentHash for the domain, when such is used.
Having said that I think it could also be an option to have app keys for ENS names to allow application to update without having to scare their users with another enable popup or share data with earlier version easily. This should be clearly indicated to the user though as a warning when accepting such ENS name based app keys.
Similarly: App keys should work with DNS names. I am not sure I understand the rational behind refusing them. Is it really not possible to come with a normalization scheme similar to ENS ?
I’ll take the time to review the links and your post in details, but for now I had a quick comment about your last part:
Agreed that we should find a way to support non ENS names (both for generality and to remove the requirement to register an ENS domain). DNS names are indeed a good candidate and should be fairly easy to support.
Something like this is definitely needed. I’d like to engage with it more but initial reaction - it seems like the system should be designed to accommodate all DNS names. I also wonder how long it will be safe to trust the domain model - if there is a valuable payload it may become worthwhile to attempt to access wallets from forged domains.
Perhaps we can accept any app regardless of domain by requiring apps to use their own public / private keypair. Then the user proactively trusts the app (identified by keypair and not a hash of the name) similar to adding a public key to ssh authorized_keys.
**Edit: an alternative to generating new accounts per app could be to leverage existing TLS certificates, since most web hosts (whether VPS or AWS style providers) have secure mechanisms built in to store secure signed data.
I definitely agree that the EIP should offer support for all DNS names (assuming support for ENS), and with DNS names you could uniquely identify addresses just like ENS. Overall, I know there’s a different process to make a subdomain tied to a unique address on DNS than on ENS.
Short term focus on DNS support could slow down overall progress on this EIP. With other teams working on integrating DNS services with Ethereum addresses, DNS implementation may be out of the scope of this EIP.
If this EIP focuses solely on ENS app accounts, other EIPs should come out to improve DNS standards of Ethereum address creation. As soon as that happens, it should be easy adding a feature for DNS support.
They allow to isolate the accounts used for each application, thus increasing privacy.
It could be worth enumerating on the use-cases where these app keys could increase privacy, and to document how a user can take advantage of this feature to protect privacy.
For example if all a user is doing with these keys is signing messages, I can see it being relatively easy for a wallet to keep them isolated and thus prevent correlation between the keys. But if a user begins transacting with these keys, and funding them from their main account(s) then it becomes trivial through blockchain analysis to correlate the keys and provide a confidence score that they are owned by the same user.
So indeed 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, indeed there can be trail and the use of app keys would not fully solve the privacy problem there indeed.
A few comments however about this:
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
And importantly, this EIP is not only about privacy, it’s also about delegation. So even in the case where your application require funding and that we have no way to obfuscate the funding trail, I really think that there is a lot to benefit from using this standard to derive accounts specific for the application for which I can delegate signing and to use these only for a single application.
Current situation where accounts are used for several different applications and for transacting is both a privacy and a security concern but also very painful to manage if you are going to have to remember which account you are using for each specific application, and there is no standard for this to be managed in a compatible way across wallets.
So even if this is not the end of the story for the privacy problem when you need to fund the app accounts, this EIP is a potential prerequisit since any private funding method will require seperate accounts and it also brings other benefits such as delegation and UX improvements.
Added support for DNS names, using the ENS hashing scheme and authenticated by the wallet through the loading of the DNS webpage.
This can create some ambiguity when using ENS names that point to an DNS url. Thus adding an option in the .enable() that allows to specify which of the 2 the app would like to use for the app keys derivation path.
@wighawag, I’m still reviewing your links and comments, but your comments suggested me to add the following to the appkeys.enable method:
.enable() now returns the app’s root account extended public key. This should allow for the app to derive all non hardened child public keys.
If enable() options also include a challenge string the wallet will sign it with the app’s root account and will return the signature.
This should allow the applications to safely authenticate the users by verifying that they indeed own the private key of the public keys they are claiming to own.
Here is the commit that includes most of these changes:
I’m totally in favour of the steps here (insofar as I understand them!) – I was quoting a very specific point that @light made. If out of the box all the keys can be correlated – then this is a step backwards.
Theoretically today I can have multiple addresses and do my own app / key management. Was it Cipher Browser that generated like 10 addresses for you but you couldn’t label them or do anything other than switch between them?
The same as having multiple email addresses where it’s all my own opsec to keep them from not being correlated.
So perhaps this is better in the form of a question @danfinlay : given this method, how much can an external actor correlate? Can they trivially (just using the chain, not IP address or browser fingerprinting) correlate my fluffy-puppies address with my hardcore-metal address?
App Keys of each application are isolated one from another across applications because we harden the derivation path for each application keys.
So even if you had the root extended public key (coming from the mnemonic), you would not be able to compute the child public keys of any application’s keys.
However, once at the application level, since the application sub path is not constrained, an application can choose to use non hardened indexes and would thus be able to compute the extended public keys (and thus addresses) of all this app’s accounts from the application’s root public key.
Indeed and I’ll try to explain why this proposal allows to be in a better state than currently in terms of privacy.
It will allow to make using a new account for each application a default. So instead of having accounts used for several applications you will have separated accounts by default. If you don’t need funding then that’s fully private.
If you need funding there is indeed a potential correlation by following the funding trail. Even in that case, it’s already better than the status quo and for several reasons:
Following the funding trail does not give you certainty that these accounts belong to the same person, only some probability.
If you use a mixer to fund the app account then it would obfuscate this trail. And with our proposal you have a proper way to create and manage a large amount of applications specific accounts.