-
Notifications
You must be signed in to change notification settings - Fork 480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-custodial Wallet Hosting & Sync #3442
Comments
Inspiration: You mentioned zksnarks. That got me thinking here. I had an idea for a small but significant change to your approach that I think could ease a few of our problems. But I wanted to run it by you before I go too deeply into using it for use cases and diagrams.
An auth request (login or password change) contains:
The response is The From this point, I can think of several ways that it makes this system at least a little bit smoother:
It just seems like a tighter system. More naturally decentralized. Are there downsides I haven't thought of? Did LBRY already consider and reject this idea at some point? Is this somehow a bad idea for Odysee? Our plan involved decrypting the wallet in-browser for Odysee anyway, right? I can think of one hypothetical downside: Without taking the time to think too deeply about it, my intuition tells me that this design may make it easier to clobber conflicting changes between two devices if there's a password change involved, that the previous design would stop us from doing. We just have to think extra carefully about it. Perhaps related: Some quick thoughts about tightening things up a bit more:
|
just to make sure i understand the process: to make a new account, you send the server a loginPublicKey and a downloadKey to get the wallet, you use the loginPublicKey and the downloadKey to set the wallet, you use the loginPublicKey and downloadKey and sign the request with the loginPrivateKey (you didn't say this, im just making it up) to make a session which lets you interact with a particular service, you send it a loginPublicKey, a downloadKey, a few others fields, and sign it all with the loginPrivateKey is that right? so the idea is that you can't really do anything on a service until you get your wallet and get the private key out? |
this seems like it could work. next step to verify that is probably to draw out all the interactions. you could get a similar effect by doing |
sure. a private key is just some random bytes, and you derive a public key from the private key. |
I should have given some example interactions.
Okay, this was a bit of an oversight on my part. I'll assume the hard case, that you're talking about the user installing onto a second device (or recovering from backup). I was originally thinking that you don't need the loginPublicKey for this part, only the downloadKey. However, the server still needs to know which user is requesting their encryptedWallet in the first place. Expecting the user to somehow know their loginPublicKey before they have their wallet on a new device is possible but obviously very unfriendly. So, I suppose we'd still need a username field (email address, etc) separate from the id (loginPublicKey). We could allow changing the username, but their id wouldn't change. The username would be relatively low stakes just like downloadKey: it would only be used for downloading the encryptedWallet. With that in mind:
So now, the user only needs a username and password to set up a new device. The server does not get the loginPublicKey for this part.
Everything other than downloading encryptedWallet, yes.
To perhaps clairfy, the only reason I mentioned sending downloadKey during this request was to set it on the server side, so that another client could download the encryptedWallet after. It could and perhaps should be sent in a different request. Othrewise, yes.
Again, don't need downloadKey here, unless we choose to set it in this request along with the wallet. |
Note that the only reason I made downloadKey separate from the login keypair was that it was available without the wallet. With what you have here, loginPrivateKey is available without the wallet already. So we can get rid of downloadKey (giving us more bytes for security) and just require the auth token to download.
However, a change of password would mean change of loginPrivateKey and thus loginPublicKey, and thus a change of identity according to the design I've laid out. So, it's a different system but maybe that's fine. It would be like your loginKey system plus the benefit of no secret crossing the wire, so it still fixes the password breach problem. But given that login keypair can change, you'd lose these benefits from above:
The first and last may be minor. Not sure about the middle. In general I like the elegance of an identity that never changes, but again maybe there's a downside I'm missing. |
i didnt think about that. so its a question of whether your identity is tied to something like an email address, or to a private key. we'll have to think about that |
Putting this here so I don't forget: it would be nice if this also worked with social login. Maybe there's a way to get a string from the social login params and use that as a password? Or store a password with the social login service. |
lbryio/lbry-desktop#6792 I made a suggestion to the LBRY desktop and mobile clients on better wallet management, I am for these features since it will allow your LBRY account/wallet to only have one seed phrase and not a whole bunch of seed phrases over time as you login to new devices. |
(draft)
Motivation
Your wallet file stores important data that apps need to access. There's no convenient noncustodial way to back up your wallet or keep it synced across multiple apps. If you use several LBRY apps, you'll end up with many separate wallets.
Goals
noncustodial
multiapp
onepw
pwreset
realtime
wallets synced live between apps (at least it should feel like its live). relaxing this constraint since realtime stuff is moving out to federation or local storagedecentralized
userfriendly
Plan
1. move as much stuff out of the wallet as possible
encrypted blob in channel?unsynced, or the sync is done by the app2. hosted wallet sync and oauth
set up https://lbry.id service to host wallets and provide oauth (should be open-source and documented so anyone can run their own auth service)
support 2fa?
3. client-side signing via lbry.id or js or browser plugin (a la metamask)
Once this sync protocol is adopted, apps will need a way for users to sign transactions to interact with LBRY. This must be done client side to satisfy the
noncustodial
requirement. This can be done (in increasing order of security) custom in the app via JS, or using a popup like Deso, or a browser extension like Metamask (which could also do hardware wallet support).Terms
Server Operations
register
Register a new account
params: id, password, version
response: authToken
errors: version not supported, id already exists
oauth
Support the standard Oauth flows. We'll probably integrate with existing IDP project
getWallet
Get the current wallet data
params: authToken
response: version, encryptedWallet, sequence
errors: invalid authToken
putWallet
Store new wallet data
params: authToken, version, encryptedWallet, sequence
response: ok
errors: invalid authToken, version not supported, sequence mismatch
changePassword
This is the same as a putWallet, but also changes the loginKey.
params: authToken, version, loginKey, encryptedWallet, sequence
response: ok
errors: invalid authToken, version not supported, sequence mismatch
info
Get info about a user
params: authToken
response: id, version, sequence
websocket
Connect to websocket to be notified when new wallet data is stored
params: authToken
Common flows
New account
TODO
Connect an app
TODO
Conflicting writes
TODO
I forgot my password, what can I do?
TODO
Multiple user apps (desktop + mobile + paper backup)
TODO
UX Considerations
Different wallets have different needs. If you just started an account, its no big deal to lose your wallet. If you have a lot of channels/claims/lbc in there, you want more backups and security.
Security
how to do this so its secure? what's the threat model?
prolly want an audit for this, but shouldn't block deployment
Rabbit holes
password resets
oauth and multiple apps
secure client-side signing via lbry.id
migrating odysee to this system
phishing
do we have to have the same password across multiple apps?
Extras
When unlocking, run sync first to make sure latest version is stored in cloud
Unlock via QR code or copying a string?
optional passcode to wrap root key locally
encrypt data with intermediate key, then encrypt that key with the password. this lets you back up your wallet encrpytion key on paper
does this work with multiple apps? can you have separate passwords across multiple apps? prolly not… so then a malicious app could get your odysee password
can you login with zksnarks? proof you know some encrypted string without revealing that string?
tell ppl when their passwords are poor using haveibeenpwned.com
outline what changes sdk has to make
should we store an
updatedAt
timestamp for wallet changes?Alternative ideas
no wallets. everything is on-chain and can be restored from seed
store wallet in public cloud (s3, google drive, etc). define storage location in channel claim.
onepw
requirementRelated issues
#2641
References
The text was updated successfully, but these errors were encountered: