Encrypted Collaborative Editor built with Solid

Dear Forum!

@A_A, a few of our colleagues and me have built a collaborative editor using the Solid specification for a university project.

The final result is called SolidCryptPad and can be found here.

Why SolidCryptPad?

  • Collaborative Editing - You can open your files and edit them, either alone or together with your friends and colleagues.

  • Link Sharing - You can invite friends and colleagues to collaborate simply by sending them a link to share single files or entire folders. Just want to show them your work? You can specify read-only access as well!

  • File explorer - You can see the folder structure inside your pod and navigate wherever you want. You can of course create or delete files and folders.

  • Encryption - All features have been built primarily with security in mind. This of course does not guarantee bulletproof security but we tried our best :smile:. The encryption scheme we used is explained here, and we are happy to clarify any points which are unclear.

The application as it is is fully functional but some things can still be considered quite rough around the edges such as some UI elements.

We would all be happy for some feedback, suggestions or pull requests from the community as we would love to see this application evolve further!

5 Likes

Interesting! I’ll have to look into this further, as I’m particularly interested in e2e encryption, and how it could be paired with Solid.

1 Like

If you have any questions, don’t hesitate to ask!

The main idea of our E2E encryption is, to have one encryption key per file which is only known to the user, and people with whom the user shared the key. To manage and share the encryption keys we save “keystores” on the Solid pod which map urls to keys, and which are indirectly encrypted with the master password of the user. So the user only needs to remember one password, that is also easily changeable.

Linked data was out of scope for this project, so we didn’t make considerations into this direction.

Encrypting and decrypting linked data should be rather trivial. Also one could make an encrypedFetch and pass it to e.g. solid-client, to work with linked data in the usual way, even though the data is E2E encrypted.

Describing the encryption with linked data seems like a hard problem. If data is encrypted on the pod, we would still like other applications to be able to use this data. With Solidcryptpad, they would have to reuse the exactly same encryption algorithm, which is not very interoperable. I guess for interoperability we would need something like (1) a standard as XML encryption, where the encrypted data is described so the application can figure out how to decrypt it just by using this metadata, or (2) a commonly used encryption library.

So in summary, I think Solidcryptpad makes a decent attempt at E2E encryption, but for interoperability there’s still a lot of considerations to make and maybe standards to develop.

2 Likes

Yeah, I read through your document, and it is one way of implementing it. More commonly, I’ve seen key encryption keys be used, so each user has the encryption key for the file/data encrypted with their public key and then their private key is encrypted with a value derived from their master password. So multiple users don’t share encryption keys, instead each user has a specific key just for them. (This is more similar to how, say, protonmail implement their encryption, though that’s backed by openpgp and some other stuff)

1 Like

Oh, also, @A_A, I’ve sent @hld0 some feedback privately via the messages system on the forum.

2 Likes

Thanks for the feedback!

We’ve discussed such an encryption scheme with our tutor, but decided against it, because we could not find a user-friendly way to do link sharing with public keys. From what I understand, the scheme you describe requires the person, who shares the file, to know all public keys of the recipients in advance. This (1) limits it to a defined set of people, instead of “everyone who has this link” and (2) requires to retrieve the public keys securely (e.g. over a messenger, or a central trusted server). At least that was the result of our thought process back then, maybe we forgot something. With this in mind we decided against public+private keys to have a better user experience.

I’ve taken a look at Proton Drive encryption. From what I understood, they simply trust their centrally stored public keys of the users (and allow manual verification of public keys by users) to circumvent the problem of sharing public keys (2).
For link sharing, they also use the same encryption key for all users, without any asymmetric encryption. From my point of view this does not differ significantly from our approach.

1 Like

Hey, I’ve given the app a try and I like it, good job :D.

One improvement that comes to mind is allowing shared links to be viewable without logging in. That way this can be useful even for non-Solid users and be a nice way to get people into it. They could read the documents just with the link, but in order to write they’d need to log in with their Solid account.

I also tried using the app without setting any passwords to see if I could see the unencrypted data, but it seems like that didn’t work properly. Maybe passwords should be required? Or at least make sure that this works.

On the data side, I know that linked data and interoperability were out of the scope, but In case you’re interested I’ve been trying to implement a CRDT approach for Solid as well. Although my approach is for a much simpler use-case; real time editors are certainly on another league. I’m working on a vocab to declare the CRDT operations, but one immediate problem I can see is that it’s probably not compatible with yjs’s data structure. An additional challenge is adding encryption on top of all this, of course. But it’s very interesting to see these things in Solid starting to appear :).

Maybe a half-way approach would be to just declare the CRDT/encryption algorithms in RDF and have the whole encrypted blob in another property. That way, applications could be interoperable but if they don’t support the CRDT/encryption algorithm at least they could show an error “encryption algorithm ‘whatever’ not supported”. I imagine something like this:

<#it>
	a crdt:TextDocument ;
	crdt:crdtAlgorithm "yjs" ;
	crdt:encryptionAlgorithm "keystores" ;
	crdt:keystores </solidcryptpad-data/keystores/keystores.json.enc>, </solidcryptpad-data/keystores/root.json.enc> ;
	crdt:data "U2FsdGVkX1/ooT+U69NASWTXeEhzi97RfpuRxyH73Y9NR0xj0l17+8pafKHsFsmcDfFWP371sjGHQ4anacIxSg==" .

And finally, I have some comments/doubts about the synchronisation mechanism. It seems like the clients are actually connected to each other using WebRTC, and the Solid POD is used to store the data that will be needed for new clients to join, right? That’s actually very nice, because even if the Solid POD goes down for whatever reason, the clients can continue working with each other. But one concern I have is that this seems to create a lot of unnecessary network requests.

For example, imagine I have two clients open: A and B. When I make a change in A, this both writes the data in the POD and sends it to B through WebRTC. So far so good, but then when B gets the update, it’s in turn writing data in the POD again. I’m aware that the way CRDTs work sometimes this is expected, because part of the information stored is what’s the latest operation that a given node has seen. But seeing that every tiny update causes a PUT request that overwrites the entire document is concerning from a performance point of view, specially if this were to be used in mobile devices or other data-sensitive contexts. And I think this is exacerbated because CRDTs are notoriously infamous for creating a huge data overhead. It would be a lot better to just update with the new information, rather than overwriting the entire document.

In any case, I guess those are probably not real concerns you have at this point, but it’s food for thought :).

1 Like