status-web
status-web copied to clipboard
Use Ethereum wallet to create and access a profile
What
- Use Ethereum wallet for creating a new profile and accessing it from multiple environments (i.e different devices or browsers)
- See https://www.figma.com/file/DaktYgy62CJEKE9Zqf7WTS/Web-UI?node-id=3%3A414647 for designs (Web UI > Login / Setting up a Profile > Connect Ethereum Wallet)
How (for example)
- See https://github.com/status-im/js-waku/issues/73
Prerequisities
- Community is embedded in another dapp
- Wallet account was already pre/generated or imported in those multiple environments
- Identity is not the one created by native Status apps (i.e. desktop or mobile)
- No seed phrase or private key is requested from the user
How
- Create a new account in wallet and use exported private key as the profile
- Create private key within the app and import it into a wallet
- Status browser extension
- Use a signature generated by the wallet to always create same private key within the app
- TBD
Proposals
Table
Status: draft Disclaimer: now only in theory and without research and security teams' review Disclaimer: grades are subjective
| In-app key generation | In-app key generation from wallet signature | In-app key generation with wallet encryption and decentralized backup | In-wallet key generation returned as value | In-extension key generation with RPC methods for per-session signing and encrypting | In-native key generation with Vac protocol pairing | In-app key generation with password manager import via <input> |
In-native key generation via RCP method and WalletConnect protocol pairing | |
|---|---|---|---|---|---|---|---|---|
| ID | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| Status | Stable | Stable | Stable | Idea | Idea | Idea | Stable | Idea |
| Estimation | XS | S | L | L | XL | M | S | L |
| Supported wallets | - | - | - | - | ||||
| Exposes private key | No | Yes | No | No | No | Yes | Yes | Yes |
| Preserves identity across in-house clients | No | No | No | No | Yes | Yes | No | Yes |
| Domain binding/origin checking | No | No | No | Yes | Yes | - | ||
| Backed up | - | Yes | No | No | - | No | ||
| Recoverable | Yes | Yes | Yes | Yes | - | No | ||
| Exposes wallet account | No | Yes | No | No | No | No | ||
| Encryption | AES-256-GCM, ECIES (secp256k1) | |||||||
| Key generation | ECDSA (secp256k1), Crypto.getRandomValues(new Uint8Array(40)) (hash) |
ECDSA (secp256k1) | ||||||
| Key derivation path | BIP43, EIP-1581 | |||||||
| Signing | ECDSA (secp256k1), PBKDF2, SHA-3-256 (keccak256) | |||||||
| Key exchange | - | - | - | Return value | - | X3DH, 35/WAKU2-NOISE, 37/WAKU2-NOISE-SESSIONS | - | |
| Identity encoding | base58 | |||||||
| Security grade | B | B | B | A | B | C | ||
| Usability grade | B | A | ||||||
| Ecosystem fit grade | A | B | C | A | B | C | ||
| Ecosystem outlook adoption grade | A | B | C | - | A | C | ||
| Signing message format | EIP-712 | |||||||
| Derived from a user seed phrase | No | No | Yes | Yes | Yes | No | ||
| Deterministic key generation | Yes | - | Yes | Yes | - | - | ||
| References | EIP-2224, EIP-712, EIP-4361 | EIP-1775 | 2/ACCOUNT, 26/WAKU-PAYLOAD | |||||
| Demo | ||||||||
| Review | ||||||||
| Personal inclination at the moment (see last edited date) | ☝️ |
Notes
Keywords
key management, private, public, secret, account, sign, log, auth, origin, identity, federated authentication, backup, webauthn, passkey, sync, verification code, issuer, phishing, domain binding, password, cryptographic key pairs, end-to-end encryption, phishing resistance, cross-platform, public key cryptography, credentials, proximity proof, local key agreement, CTAP operation, factors, scope, cookies, secure context
We should value privacy more
https://ethereum-magicians.org/t/meta-we-should-value-privacy-more/2475
- Mixers
- Keep wallet software stateless
- For every dapp a separate account
- Deterministic scheme
- so we would use different BIP-32 paths for each dApp.
Waku Key Management
https://specs.status.im/spec/10#keys-management
- The protocol requires a key (symmetric or asymmetric) for the following actions
- signing & verifying messages (asymmetric key)
- encrypting & decrypting messages (asymmetric or symmetric key).
- https://github.com/status-im/js-waku/issues/73#issuecomment-918134714
- DID as identifier, not chat keys
- https://discord.com/channels/864066763682218004/892839110073520128/915558795533496331
- [@]cammellos so I had a chat with [@]John_ and I think there is an important detail that impact the discussion above. The aim for mobile/web sync'ing is mainly to onboard users on the Status mobile app FROM a DappConnect Chat website. E.g., a user uses the uniswap trollbox (built with DappConnect Chat SDK) and setup their profile and has some good fun. As they want to troll on the go,they install the Status chat app and sync their web profile to the status chat app.
EIP-191: Signed Data Standard
EIP-712: Typed structured data hashing and signing
https://eips.ethereum.org/EIPS/eip-712 https://ethereum-magicians.org/t/eip-712-eth-signtypeddata-as-a-standard-for-machine-verifiable-and-human-readable-typed-data-signing/397/6
- We are seeing growing adoption of off-chain message signing as it saves gas and reduces the number of transactions on the blockchain. Currently signed messages are an opaque hex string displayed to the user with little context about the items that make up the message.
- Just encoding structs is not enough. It is likely that two different DApps use identical structs. When this
happens, a signed message intended for one DApp would also be valid for the other. The signatures are compatible.
This can be intended behaviour, in which case everything is fine as long as the DApps took replay attacks into
consideration. If it is not intended, there is a security problem.
- The way to solve this is by introducing a domain separator, a 256-bit number. This is a value unique to each domain that is ‘mixed in’ the signature. It makes signatures from different domains incompatible. The domain separator is designed to include bits of DApp unique information such as the name of the DApp, the intended validator contract address, the expected DApp domain name, etc. The user and user-agent can use this information to mitigate phishing attacks, where a malicious DApp tries to trick the user into signing a message for another DApp.
- https://github.com/ethereum/EIPs/pull/712#issuecomment-330501545
EIP-2224: Automatic Authentication Signatures For Web3
https://ethereum-magicians.org/t/automatic-authentication-signature/2429 https://medium.com/@wighawag/automatic-authentication-signatures-for-web3-dcbcbc64d6b5 https://medium.com/@wighawag/3-proposals-for-making-web3-a-better-experience-974f97765700
- Authorization fatigue
- Origin checks
- This means another application could request the same signature. Hence the fully automatic authorization signature scheme mentioned here can’t be used since a malicious application would simply request the same signature without requiring user approval. A proper implementation would indeed require the user’s vigilance to not sign such message on a malicious application. This leads to a potential vulnerability against authorization fatigue (especially if you can’t rely on a web browser to store your signed-seed, in which case you would need to request signature for every session), similarly to what I mentioned about cryptokitties.
- Unsafe signing rpc: eth_sign https://github.com/status-im/status-mobile/issues/8909#issuecomment-530122209
- Of course as mentioned such scheme is not for everything since it relies on the user trusting the application’s front-end in question
EIP-1581: Non-wallet usage of keys derived from BIP-32 trees
https://eips.ethereum.org/EIPS/eip-1581
- https://ethereum-magicians.org/t/non-wallet-usage-of-keys-derived-from-bip-32-trees/1817
- Using keys under the BIP32 tree for these purposes would allow the user to migrate the whole identity from one software to the other using the BIP39 mnemonic alone, since everything else would be derived from there.
- Key types should be generic. “Instant messaging” is a good example whereas “Whisper” is not. The reason is that you want to be able to use the same identity across different services.
- Implies that access to a dApp specific private key is given to the dApp. I believe this is not ideal as it means the dApp now needs to properly handle the private key.
- Another solution would be to provide a generic API that supports several encryption. An idea would be to use CryptoSubtle as the API reference and assume that in the Browser world, some of the encryption supported by Crypto Subtle should be supported by the Wallet API.
EIP-1775: App keys, application specific wallet accounts
https://eips.ethereum.org/EIPS/eip-1775
- API for getting exact account/app key which has been used for app
- Multiple identities per app
- Determinist key generation per app
- https://github.com/ethereum/EIPs/pull/1775#discussion_r266664449
- Cross application keys (non crypto accounts)
- With names to derive UIDs
- Applicaition keys
- App UIDs
- Personas
- App specific HD (hierarchically deterministic) subpath
- Performance issue for hardware wallets
- HD depth
- 10 levels
- Keycard
- Ledger Ethereum app
- Cross application keys (non crypto accounts)
- https://ethereum-magicians.org/t/eip-erc-app-keys-application-specific-wallet-accounts/2742/30?u=feliciomununga
- Edit: Just talked to Ledger CTO we will do a benchmark (time / depth) analysis and report the findings.
EIP-2844: Add DID related methods to the JSON-RPC
EIP-1024: Cross-client Encrypt/Decrypt
https://ethereum-magicians.org/t/eip-1024-cross-client-encrypt-decrypt/505 https://ethereum-magicians.org/t/the-ux-of-eip-1024-encrypt-decrypt/1243 https://github.com/ethereum/EIPs/pull/1098
EIP-4361: Sign-In with Ethereum
Contracted by Ethereum Foundation and ENS to an org called Spruce in an open "tender", funded with 40M+ USD by many investor, to do... https://eips.ethereum.org/EIPS/eip-4361 https://ethereum-magicians.org/t/eip-4361-sign-in-with-ethereum/7263
- Already, many services support workflows to authenticate Ethereum accounts using message signing, such as to establish a cookie-based web session which can manage privileged metadata about the authenticating address. This is an opportunity to standardize the sign-in workflow and improve interoperability across existing services, while also providing wallet vendors a reliable method to identify signing requests as Sign-In with Ethereum requests for improved UX.
- Both the wallet and relying party have to implement this specification for improved security to the end user. Specifically, the wallet MUST confirm that the message is for the correct domain or provide the user means to do so manually (such as instructions to visually confirming the correct domain in a TLS-protected website prior to connecting via QR code or deeplink), otherwise the user is subject to phishing attacks.
- In some implementions of wallet sign-in workflows, the server first sends parameters of the message to the wallet. Others generate the message for signing entirely in the client side (e.g., dapps). The latter approach without initial server interaction SHOULD be preferred when there is a user privacy advantage by minimizing wallet-server interaction. Often, the backend server first produces a nonce to prevent replay attacks, which it verifies after signing. Privacy-preserving alternatives are suggested in the next section on preventing replay attacks.
- Prior to signing, the wallet MAY consult the user for preferences, such as the selection of one address out of many, or a preferred ENS name out of many.
- Wallets MUST check that the domain matches the actual signing request source.
- This value SHOULD be checked against a trusted data source such as the browser window or over another protocol.
- If any resources specified in resources change, the server SHOULD invalidate sessions appropriately. However, the interpretation of resources is out of scope of this specification.
- https://blog.spruceid.com/sign-in-with-ethereum/
- https://blog.spruceid.com/sign-in-with-ethereum-proposed-architecture/
- provide a direct form of authentication to Web2 services using message-signing and claims aggregation directly from a user’s Web3 wallet and ENS, rather than a traditional intermediary
- using newly derived Ethereum addresses on a per-interaction basis, or incorporating zero-knowledge techniques to reduce correlation.
- https://blog.spruceid.com/ethereum-identity-review-of-eips-over-time/
- Additionally, signed_data could never be an Ethereum transaction, because it cannot be one RLP-structure, but a 1-byte RLP payload followed by something else. (EIP-191)
- This EIP was a response to EIP-725, due to EIP-725 requiring the creation of a smart contract and not being free for the end-user. The specification additionally accounts for key rotation without changing the primary identifier of the identity. (EIP-1056)
- https://blog.spruceid.com/spruce-raises-7-5-million-to-speed-the-development-of-user-controlled-id-and-data/
- We will be scaling up efforts on SpruceID, our open source toolkit for decentralized identity, and Kepler, our decentralized and permissioned storage solution.
- https://blog.spruceid.com/sign-in-with-ethereum-wallet-support-eip-191-vs-eip-712/
- https://blog.spruceid.com/from-sign-in-with-ethereum-to-session-keys/
- One solution is autosigning, which allows applications to automatically use the user’s keys for certain actions without the wallet displaying a confirmation prompt. This approach has been considered previously by the WalletConnect protocol and several wallet providers, but it has since been discouraged due to its potential for gross overreach of permissions. There is a high potential for abuse if not implemented carefully.
- Other approaches that require the user to input their seed phrases or private keys into the browser window have been categorically deemed by the community to create unacceptable levels of risk. The browser DOM is by far a less secure environment than hardware wallets and browser extensions, readily vulnerable to common cross-site scripting (XSS) attacks and weak content security policies.
- Mirror offers users session keys in the form of their “Signing Keys” which authorizes a key to sign on the user’s behalf to avoid wallet interactions. After signing, the user isn’t prompted again to sign for any action they perform on the platform:
- https://twitter.com/lindseywinder1/status/1480919369395933189?s=20&t=Qq4dBALwJo2bebsXqKbrLA
- I think it's a copy issue. If you said "import wallet" instead of "sign up using seed" I'd look at this the same way I do when using metamask or trust. "Sign up" makes the user think you're storing it like an email address
- The browser DOM is by far a less secure environment than hardware wallets and browser extensions, readily vulnerable to common cross-site scripting (XSS) attacks and weak content security policies.
- https://blog.spruceid.com/sign-in-with-ethereum-is-a-game-changer-part-1/
- For full transparency, the specification states that the entire message and fields must still be made available in additional sub-interfaces (such as a detail view).
- The specification also introduces additional security requirements for wallets, such as domain binding to prevent phishing attacks
- and nonces to prevent replay attacks,
- https://blog.spruceid.com/spruce-completes-first-security-audit-from-trail-of-bits/
EIP-1056: Ethereum Lightweight Identity
https://eips.ethereum.org/EIPS/eip-1056
- it must also be possible to rotate keys without changing the primary identifier of the identity.
- The identity system should be fit to use off-chain as well as on-chain.
Extensible crypto for wallets
https://ethereum-magicians.org/t/extensible-crypto-for-wallets/2546
- A dApp is allowed to supply its own algorithms
- https://github.com/ethereum/EIPs/pull/1098#issue-324530972
- Add web3.eth.encrypt and web3.eth.decrypt functions to JSON-RPC
- https://github.com/ethereum/EIPs/pull/1098#issuecomment-598636328
- Sign each public key with eth identity
- https://github.com/decentralized-identity/didcomm-messaging/blob/main/docs/spec-files/encryption.md
- DIDComm Messages are encrypted with the keys of a single DID.
- https://github.com/ethereum/EIPs/pull/1098#issuecomment-1186234296
- https://github.com/ethereum/EIPs/pull/1098#issuecomment-1186529416
- The xpub (and ypub, zpub) allows you to derive the public keys for a derivation path without the private key. If you give an xpub to another party, they can generate all public keys for all keypairs derived from the starting keypair.
- Tornado cash
- Note account key
- Additional on-chain backup of note account
- Request encryption public key
- would like your public encryption key. By consenting, this site will be able to compose encrypted messages to you.
- Remove account information from current browser's session
- https://github.com/ethereum/EIPs/issues/130
- Currently I'm leaning towards letting various dapps and/or whisper-like protocols handle the key management themselves and using your main Ethereum keys to "provision" these encryption keys (by signing the public encryption keys) and associate them to your identity through a registry or similar. But I do agree that there is value in using your keystore for encryption keys as well.
- https://github.com/MetaMask/eth-sig-util/pull/18
Misc.
- https://eips.ethereum.org/EIPS/eip-2333 (EIP-2333: BLS12-381 Key Generation)
- https://eips.ethereum.org/EIPS/eip-2335 (EIP-2335: BLS12-381 Keystore)
- https://eips.ethereum.org/EIPS/eip-725 (EIP-725: General key-value store and execution standard)
- https://eips.ethereum.org/EIPS/eip-1078 (EIP-1078: Universal login / signup using ENS subdomains)
- https://eips.ethereum.org/EIPS/eip-5131 (EIP-5131: ENS Subdomain Authentication)
- https://eips.ethereum.org/EIPS/eip-107 (EIP-107: safe "eth_sendTransaction" authorization via html popup)
- https://eips.ethereum.org/EIPS/eip-927 (EIP-927: Generalised authorisations)
- https://eips.ethereum.org/EIPS/eip-1207 (EIP-1207: DAuth Access Delegation Standard)
- https://eips.ethereum.org/EIPS/eip-1344 (EIP-1344: ChainID opcode)
Code
- Gitcoin
- opensea
- tornadocash
- Xmtpjs
- Wallet connect
- Rainbow kit api (https://twitter.com/markdalgleish/status/1554253323720884224?s=21&t=e-HaC8JyJVC79fldKmZbOQ)
- Metamask
- Mirror.xyz
- Snapshot.org
- Siwe
Reasons
~~Status: draft~~
See table above for detailed comparison, following only lists main reasons which I think should help with picking a proposal.
Proposal 1
Pros
- Has been implemented once already, thus requiring lower effort (see https://github.com/status-im/status-web/blob/b82bf0c0e5d884566f11e92209f573a94641b5cc/packages/react-chat/src/components/Modals/WalletModal.tsx)
Cons
- Major wallets (providers) do not support a (standard) signing method (via RPC API) to check actual origin (domain) of the page that would embed Community, thus exposing user to a possibility of giving up a private key of completely different Community
- MetaMask
- https://docs.metamask.io/guide/signing-data.html#signing-data-with-metamask (sign)
- Coinbase
- https://docs.cloud.coinbase.com/wallet-sdk/docs/injected-provider (sign)
- https://github.com/coinbase/coinbase-wallet-sdk/blob/3ef9074b27098fe718ab93d2116fb2d2c1533ab3/packages/wallet-sdk/src/provider/JSONRPC.ts (sign)
- Rainbow
- https://github.com/rainbow-me/rainbow/blob/c541cbb4e3e327487745b588f1d66f2457145105/src/parsers/requests.js (request)
- https://github.com/rainbow-me/rainbow/blob/c541cbb4e3e327487745b588f1d66f2457145105/src/utils/signingMethods.ts (sign)
- Other standard methods that Ethereum clients should implement
- https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign (sign; only
eth_sign)
- https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign (sign; only
- MetaMask
- Suggests that a wallet account used for signing represents identity at which user could be addressed, or reached, at like in case of XMTP, which is not the case and thus misleading
Proposal 2
Cons
- Exposes wallet addresses as users of the dapp
- Even though encrypted, represent an additional service that can be targeted for denying service or obtaining private keys without user consent
Proposal 3
Cons
- Requires all major wallets to implement a standard which has been in "stagnant" state for years
Proposal 4
Pros
- Doesn't require us to wait for other providers to agree and implement the solution
- Preserves user identity across all platforms
- Protects user from a modified source code trying to obtain a private key
- Through our official channels we can communicate to users that only our native app and the extension can and should be used to manage seed phrase or private keys
- Spreads org's awareness through visibility (in App Store, Web Store) and differentiability from other wallets (by separation)
Cons
- Larger effort
- Unknowns in regards to providing and securing access to only relevant pages without prompting user all the time on refresh or reopen
- ~~Unknowns in regards to generating same private/chat key despite provided seed phrase~~
- ~~Chat keys (at least on mobile) seem to be generated randomly, not in order~~
- ~~Number and performance needed to generate all possible private keys until matched with provided public key~~
Questions
~~Status: draft~~
Product
- What's the actual product spec?
- Shouldn't throwaway profiles be labeled as such (e.g. field in waku message)?
- Shouldn't throwaway profiles be removed from Community's members list after a while (TTL)?
- When?
- Why not have it valid only for 24h, for example? In which case it could be preserved in browser storage even unencrypted, I think.