ssbc / ssb-server

The gossip and replication server for Secure Scuttlebutt - a distributed social network
1.68k stars 164 forks source link

Multiple device support #252

Closed pfrazee closed 5 years ago

pfrazee commented 8 years ago

Presently, users can't share keypairs between devices, because doing so risks publishing two messages with the same sequence number, which is a feed-corruption event.

Because identities are connected to keypairs, this forces users to create multiple separate identities. How can we solve this?

pfrazee commented 8 years ago

The "Aliased Keypairs" solution has the user produce new keypairs for each device, and then have the keypairs' feeds announce equivalence with each other. A would announce I am == to B and B would announce I am == to A. SSB programs would then treat the two identities as equivalent.

Problems with this:

pfrazee commented 8 years ago

The "CP Devices" solution has the user copy their keypair between their devices, and then have the devices synchronize before publishing new messages to the network. This way, the devices ensure they never publish a conflicting sequence number.

Problems with this:

pfrazee commented 8 years ago

The "Hosted" solution keeps the keypair in an accessible server (probably a VPS). The users' devices connect to this node in order to publish new messages.

Problems with this:

dominictarr commented 8 years ago

These three approaches would all have pretty steep tradeoff. only being able to publish when you are online would work, but turn it into a client-sever protocol which isn't really in the spirit of ssb.

ahdinosaur commented 8 years ago

:+1: for aliased keypairs, as that also ties in with key revocation.

pfrazee commented 8 years ago

Both "Hosted" and "CP Devices" introduce coordination into the protocol for the first time. On the other hand, aliased keypairs complicate the datamodel quite a lot.

wesleytodd commented 8 years ago

I think I also like the aliased keypairs FWIW. After reading through the discussions, I can totally see why it is the most consistent with underlying principals of SSB.

What happens when a user only sees one half of the alias messages, do they then have enough information to find the other half if they dont already follow that other user? Would this result in them getting only half the users messages?

pfrazee commented 8 years ago

@wesleytodd an alias announcement will involve two messages, one published by each feed, linking to the other. So you'll see one of those announcements, and then your software will know to fetch the other feed. So, yeah, you'll only get some messages until you fetch both feeds.

We need to figure out exactly what aliasing means. Even with an alias, the data-model will have to treat each feed as separate, because the logs will publish in independent orders.

dominictarr commented 8 years ago

Our application/protocol has advanced a great deal since we first dicussed aliases, so I think what we need to discuss how aliases would affect the various features we have: follows, links, names, private messages?

pfrazee commented 8 years ago

In some ways, it's a good thing that different devices are different identities. I might prefer to send a PM to a friend's personal device only, and exclude work devices.

I'd expect aliases to do the following:

dominictarr commented 8 years ago

Also, you may want to subscribe to different things on different devices. I check personal email on my phone, but not github email.

I think there is an important security edge case about how we handle old messages from another account. There are probably a variety of ways you could represent the equivalence of the two feeds and we'd need to think these all though, security wise.

handling the feeds as combined, and addressing messages to all or a subset of devices would be simple enough too.

ahdinosaur commented 8 years ago

There are probably a variety of ways you could represent the equivalence of the two feeds and we'd need to think these all though, security wise.

mhm, owl comes to mind. same as, supersedes, superseded by, ...

dominictarr commented 8 years ago

I've been thinking that since this is relatively hard, we should figure out private groups before we do this. one way groups would be useful, and pretty easy to implement.

ahdinosaur commented 8 years ago

@dominictarr that makes sense, as this is all part a larger question of how to represent identities, whether as an individual or a group.

ahdinosaur commented 8 years ago

relevant stumble: very dense paper on group signatures from Pond.

aredridel commented 8 years ago

Separate signing and reading keys would make this easier, would it not -- all devices have their own identity, key, but share a reading key that that is encrypted to. They can assert they're a unified identity by co-signing a statement, but still act individually.

pfrazee commented 8 years ago

@aredridel ah, that's an interesting idea! @dominictarr what do you think of that?

aredridel commented 8 years ago

It's easier to solve than group chat since the parties involved in multiple devices kinda inherently trust each other, at least until a device is compromised.

dominictarr commented 8 years ago

@aredridel my big concern here is that shared keys make you less secure - if you copy a key between your devices and loose any of them, you are compromised. if they have different keys, and loose one of them, the others are still safe.

It's like, you want an aeroplane where if one engine fails the plane doesn't crash. If one engine fail causes the plane to crash, you are safer to have one engine than two.

dominictarr commented 8 years ago

Another possibility would be to use deterministic derived keys - I need to do more research here, but there is a mechanism whereby you can "multiply" your public key by, say, hash("phone") and get a pub key for your phone, but if your phone is stolen they can't go backwards to find your root key. Although, I'm gonna have to really learn how this works, because unfortunately this is not exposed by nacl... so it would need to be implemented...

NHQ commented 8 years ago

I solved this riddle. They keys analogy needs to be paired with an ignition one. If you take the keys out of the ignition, that engine (ssb/sbot) shuts off, and refuses to replicate, perhaps sending a final message at shutoff so others know not to replicate.

Put the keys in another vehicle (application), and that local engine will have the rights to publish, which other engines of that key will later trust / oblige when they sync with the network.

This requires the users to own their keys, which is a good practice, and for ssb to handle sequence breaks, perhaps obnoxiously--which may prevent you from making the mistake of trying to run two engines at once again.

Also, what if you published to your peers first, instead of locally? Then your local would replicate you from your peers, which may prevent "sequence" discontinuities when you publish from multiple devices.

Finally, why does ssb need to treat any one set of keys as an identity, when it can replicate other ssb feeds based on their public key alone? The mechanism for signing and verifying lives in the crypto libs, and can be done "outside" of the databases core function.

aredridel commented 8 years ago

I'm late reponding to @pfraze here but delegating the choice of which device of a user's you send to to the sending user is such a rough one: that means a user has to communicate what their identities are, plus updates to that list, the context for when to use which one, and how much it matters, and prevents the case where someone starts a conversation on one device but moves mobile; smooth transition between the two is super important if you ask me.

Let the user create separate (or multiple!) identities, and separate that from devices, too. (I myself have three twitter identities; two tumblr identities, and definitely distinct work identities for email)

pfrazee commented 8 years ago

@aredridel I agree, devices aren't the most friendly abstraction-level for identity. It is good to have multiple idents, but only when the user asks for it.

dominictarr commented 8 years ago

@NHQ this is actually a pretty good idea. It's not perfect, but it is simple, and we'd be able to implement it much sooner than I had anticipated. I see two problems:

Maybe there are ways to work around these... for 2) you could have a key that is derived from your master key, or just copy the keys, or something. 1) maybe you could have multilpe devices that connected to each other and formed a consistent group. That would only work when they are both online, otherwise you'd have to log one out.

pfrazee commented 8 years ago

[edit - prematurely posted, will post the full comment in a moment]

pfrazee commented 8 years ago

@NHQ's suggesting a "publishing lock." It can't be done manually. Transferring the lock without also synchronizing the log state would allow forks in the history.

Consistent groups require a quorum to make progress. In Raft, that's simple majority (see table at bottom). For 3 devices, only 2 would need to be in communication.

That's still not very good. What happens when:

dominictarr commented 8 years ago

or, one device is turned off, but the other one is on!

NHQ commented 8 years ago

If you fork yourself, merge yourself.

bcomnes commented 8 years ago

Besides the fact we can't easily figure out exactly how it works due to lack of source, Bittorrent Sync has an interested way of handling key distribution between devices for a single identity.

You essentially create an identity on your first device A, add a mobile device by scanning a QR code on device A with phone B, and then accept the pairing request on Device A.

bret-4s 2015 12 10_1

At that point you can use the mobile device B to add device C etc. The devices are aware of all the other devices apart of the identity, and can remove devices at a later date.

screenshot from 2015-12-10 16-49-21

I believe a central server might help out with some of these transactions, but it is my understanding the key exchange is p2p (and wont even leave the local network if possible).

I think its an interesting UX that opens up a lot of options for the underlying key exchange pairing process. Unfortunately the details are hidden :cry:

matthiasbeyer commented 6 years ago

Any progress on multi-device support lately?

I'd love to try this (patchwork, scuttlebutt ...not sure about terminology yet) but multi-device support holds me back.


I just created the liber project and just pushed notes on how to do multi-device support in my setup. Maybe that helps with your discussion?

dominictarr commented 6 years ago

this thread is very old, we have most discussions on ssb it self these days. We have recently funded a grant for @mmckegg to implement multidevice, so it should be coming very soon!

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

chmac commented 5 years ago

I realise this is a very old issue. It seems like there's no current solution to this in scuttlebuttverse, unless the discussion is inside the network somewhere and not visible to me (seems entirely possible).

My suggestion is a combination of the Hosted and CP Devices strategies. I keep my key, it can exist on many devices. When I want to sync to the network, I check in with my "Hosted" component (which is really just a dumb agent). It tells me what the latest network state is (sequence numbers, whatever). I can incorporate this state into my messages, update the signatures, and then publish these signed messages to my "Hosted agent".

The copying of keys obviously creates issues, as does the storage of secrets in general. I'd suggest that's a wider issue and would solve it in a separate approach. Multi-device is not the same problem as key security, revocation, etc. There's a lot of cool ideas in that space since the advent of crypto based monies, where key security becomes really, really, really important.

If there was a conclusion to this discussion and I missed it, apologies.

PS> Not sure if this issue is really "closed" just because it's stale btw.

heyakyra commented 4 years ago

One could study how Keybase does it — https://keybase.io/blog/keybase-new-key-model — I am keenly interested in this feature!

— @coreagile https://github.com/ssbc/handbook.scuttlebutt.nz/issues/17#issuecomment-478345036

Matrix also does client key sharing, but hasn't yet implemented a full p2p-by-default model (login requires an identity/homeserver): https://matrix.org/docs/guides/end-to-end-encryption-implementation-guide/#key-sharing

jedahan commented 4 years ago

@chmac It's very possible I am missing a key piece, but I think the difficulty is that your "Hosted" agent is that it likely will have a subjective view of the world? Or are you saying 'if someone has multiple devices, only ever publish from one?'

chmac commented 4 years ago

@jedahan Looking back, my explanation was not super clear. I'll try to elaborate with an example scenario that hopefully makes it clearer.

There's some nuances here, like what to do in case of network failures while updating, etc, etc. But the core idea is that a single device becomes the "master", and it's only by talking to this device that any other devices using the same key will append to the log.

matthiasbeyer commented 4 years ago

And why not simply introducing merges for logs? That'd would solve all your problems here.

chmac commented 4 years ago

@matthiasbeyer How would merging of logs work? Is there a proposal for this documented elsewhere? My initial thought is that it would be quite a hard change, and would not be backwards compatible, but I haven’t thought about it so much, maybe there’s a better way.

matthiasbeyer commented 4 years ago

@chmac As far as I know, there is not such proposal. But I was suggesting it on various occasions for years now. If the "log" is a "DAG" (think git), all your problems with multi-device support are solved - the only thing you have to care about is the implementation in these two points:

And that's basically it. Now you got a full DAG for your "log", all algorithms for working with it are already invented and you can also easily add other devices or remove devices, because it is just authenticating the device to all other devices (and really, if you have more than 5 devices for one profile, that's really a lot and I guess not that common) or removing the authentication for a device on all others.

chmac commented 4 years ago

@matthiasbeyer I imagine this would be one possible approach. However, changing from a sequential log to a DAG is a pretty huge protocol change, and would not be backwards compatible. I'd assume it's much harder to implement this across the ecosystem than something which is backwards compatible...

jedahan commented 4 years ago

If what is published is readable by clients unaware of the change this might be fine - would love to see a PoC

ssaavedra commented 4 years ago

@chmac in your previous list of work, you propose syncing phone with computer but then require that phone publishes on its own.

What if, instead, phone just relays pendingLog to computer?

You are already requiring them to be connected, and this would at least solve the problem of resigning and race-conditions between both devices (not in this case, but think of maybe bot-instance1 and bot-instance2).

chmac commented 4 years ago

@ssaavedra Yes, you’re totally right, that makes more sense here. I was actually thinking about computer being a server rather than my laptop, where it wouldn’t have my private key. But in the example I gave, this issue topic, your suggestion definitely makes more sense. :+1:

aredridel commented 4 years ago

Oof. That means "write long thing on one device, then lose the other device" loses the update.

chmac commented 4 years ago

@aredridel Maybe there's an alternative? What about if phone keeps a copy of pendingLog until it receives those messages back as part of the published log?

aredridel commented 4 years ago

Maybe? It's tough, trying to map identities to devices 1:1 like this, or coordinate with devices that may disappear, entirely, forever, potentially all but one at once.

chmac commented 4 years ago

@aredridel I think this might work. If computer disappears, then at some point phone could be told it is now the "source of truth", and could publish messages from pendingLog to log and push them to the internet. The other devices would then push to phone instead of computer. I guess if it disappears and has unpublished messages, they're gone, but that's likely true in any situation...

aredridel commented 4 years ago

That actually doesn't sound too terrible, given a single stream of messages.

ssaavedra commented 4 years ago

I agree with that, if computer disappears, a way to instruct phone to be the source of truth or relay on a different source (computer-backup?) can be designed.

If keys are already on the devices, there should be no problem, we'd just be avoiding the race conditions by relaying messages through a single stream, but we can fall back to self-publishing if required. But beware that this kind of network partition is precisely where we want to ensure that double-writes don't happen. We should really insist users to check their other device before allowing to write from a different device.

chmac commented 4 years ago

Another major challenge here is what does the local client do with pendingLog? I know from the Bitcoin protocol that dealing with forks requires quite some thought. My understanding of SSB's internal workings is that various views get built by parsing log. I'd assume that these views assume that log is immutable. How would a pendingLog which is essentially mutable fit into that paradigm? This aspect might actually be the source of complexity here...