Protocol Engineer Philipp Krüger gave a presentation on WNFS, or Webnative File System, at IPFS Thing 2023 in Brussels, Belgium. In his presentation, he gave a comprehensive yet approachable breakdown of how we constructed our versioned and encrypted file system built on top of IPFS.
When Fission set out to create an encrypted file system that would respect user agency, it needed to meet three criteria:
- Users would be able to take their data with them anywhere and control who had access to it
- It would be available both online and offline, ensuring access no matter the user's level of connectivity
- It could be shared on different devices and types of apps (for example, you could share your data on a music app on your mobile phone and a photo app on your desktop)
Developers are used to running a server to hold user data when publishing an app online. During the prototyping process, dummy data is often stored in the browser. We realized that if we made the browser capable of running production data, it would ensure the data was local-first and private (because the data would never have to leave the device itself).
Our Frenemy, The Browser
So we began working with the browser to make this a reality. The first step was working with the WebCrypto API, which makes non-extractable key pairs possible. In addition, we wanted to ensure revocability, so we created asymmetric key pairs per app/device.
Once decrypted, data is readable in the hostile browser environment. Therefore, we needed to give not just access control but fine-grained access control. We go by the Principle of Least Authority (POLA) to ensure the user only shares what they want to share.
To do this, we encrypt all of the files. However, all those keys can be difficult to manage, so we use the skip ratchet (our CTO Brooklyn's invention!) to organize them. This also gives us temporal and snapshot access control.
Data Persistence and Key Recovery
The browser may delete local storage, so data persistence and key recovery are two important considerations.
We use IPFS to persist encrypted data outside of the browser. IPFS also has a garbage collection feature, so to be absolutely sure that data is not deleted, the user may want to store their data on a machine they keep online (i.e., their own personal node) or utilize a pinning service. Fission does not run a pinning service, but we currently persist all user file systems for free.
Key recovery can be handled by linking a device with more reliable permanent storage for your secret keys (this can be done using the AWAKE protocol). Another option is to download a recovery kit from the dashboard app (or, in the future, from any app that supports something like it).
A file system should have concurrent writes so editing can occur offline and multiple authorized users can edit without issue. We achieve this using a cryptographic tree structure (cryptree) that gives every file and folder a unique key. This enables offline access control while keeping the data encrypted and portable.
But what if two valid writes need to be consolidated? How do we determine which is the "correct one"? WNFS will merge them both by creating a directory that has both changes while also linking back to the previous data (using CRDTs) so nothing gets deleted. Then we leave it up to each app developer to determine how they want to query the history in the API and figure out how to do app-specific merges.
Privacy & Security
Previously we explained that it is important for users to have fine-grained access control because it supports user agency and resolves the issue of decrypted data in the browser.
When the user does share data with someone else, whether it's an individual or an app, this action should reveal as little metadata as possible. That's why we verify valid writes without read access (using UCANs), scramble the file hierarchy, create a flat namespace (using the CRDT structure), and split files into chunks so no one can distinguish file size.
The Rust 🦀 implementation of WNFS (rs-wnfs) is available now.