Introducing Vault: end-to-end encrypted storage, built into your pod

Pro users can now enable Vault, a zero-knowledge encrypted layer inside their Solid pod. Your files are encrypted in the browser before they ever leave your device. We cannot read them. No one can, except you.

Most cloud storage services claim to protect your data with encryption. What they usually mean is that your data is encrypted at rest on their servers, and they hold the keys. That is not end-to-end encryption. It means they can read your files whenever they choose, and so can anyone who gets access to their infrastructure.

Vault is different. Encryption and decryption happen entirely in your browser, using the Web Crypto API. Your passphrase never leaves your device. The server never sees your keys. We host the encrypted blobs, but we have no way to read what is inside them.

How it works

When you set up Vault on your Account page, a random 256-bit vault key is generated in your browser. That key is wrapped with your passphrase using AES-KW after deriving a wrapping key via PBKDF2 at 600,000 iterations. The wrapped keystore is saved to your pod at /vault/.keystore. You own it. It lives in your pod, not in a separate database we control.

Each file is encrypted with AES-256-GCM with a unique 12-byte random nonce. Per-app encryption keys are derived from your vault key using HKDF, so every app that integrates with Vault gets its own isolated key. You use one passphrase for all your apps, but no two apps can decrypt each other’s data, even if one were compromised.

A one-time recovery code is generated at setup and displayed once. If you forget your passphrase, you can use the recovery code on your Account page to re-wrap the vault key with a new passphrase. Your files are never at risk from a forgotten passphrase as long as you have the recovery code.

What gets encrypted

Any app that uses the Vault SDK stores its files in your vault automatically. File contents are encrypted. Filenames are stored only in an encrypted manifest inside the vault. From the outside, vault storage looks like a directory of opaque blobs with UUID names.

Apps that do not use the Vault SDK continue to work exactly as before, storing data as regular Solid pod resources. Vault is additive, not a replacement for the underlying pod.

Free plan users

Vault setup requires a Pro plan, because the provisioning and passphrase setup UI lives in your account dashboard. However, apps built with the Vault SDK work in plaintext mode for Free plan users. The API is identical either way. Developers write one code path; the SDK switches between encrypted and plaintext automatically based on whether a vault keystore exists in the pod.

For developers

The @privatedatapod/vault-sdk npm package is open source and available today. It works with any Solid pod server. Full documentation is at the Developer Center, including a full API reference, React integration pattern, and an AI agent prompt you can paste into Copilot or Cursor to get started immediately.

Getting started

If you are on a Pro plan, open your Account page and look for the Vault section. Setup takes about 30 seconds. After that, any Vault-enabled app will prompt for your passphrase the first time you use it per session and store your data encrypted from that point on.

If you are on the Free plan, upgrading to Pro adds Vault alongside the larger storage quota and daily backups.

This is very interesting, and definitely something a lot of people has been asking for :). But I had the impression that End to end encryption wasn’t possible given the limitations of the Solid Protocol, so I’m not sure how this works.

You mention that the @privatedatapod/vault-sdk package is open source, but I wasn’t able to find the source anywhere (something published in npm doesn’t mean it’s open source). I did manage to unpack the source maps, though, and it seems this package only consists of 5 typescript files, with no dependencies, and not even reaching 1000 lines of code in total.

So I think what this is doing is just storing encrypted blobs in a Solid POD? Meaning that from other app’s perspective, the data is not an RDF-resource, just a binary. That would mean that apps built with this Vault SDK would only be able to work with other apps using this same SDK, right? That would defeat the whole purpose of Solid (at least, the interoperability part).


These are really good questions, and honestly the kind of scrutiny that keeps open ecosystems healthy, so thank you for taking the time.

My understanding is that the Solid Protocol governs how resources are stored, accessed, and authenticated. It doesn’t place any constraints on what the bytes of a resource actually contain. The vault encrypts data client-side using the browser’s native WebCrypto API before it ever leaves the device, so the server only receives opaque blobs. The pod stores and serves them like any other resource. No server-side changes needed, and no protocol violations.

Fair call-out on the source. The source will be on GitHub shortly, I just haven’t gotten around to it yet. And yes, you read the source maps correctly: five TypeScript files, no runtime dependencies, under 1000 lines. For a package whose job is handling encryption keys, that is very much intentional. A small, auditable, dependency-free surface area is something I consider a design goal rather than a sign of immaturity.

Encrypted blobs are not interoperable RDF. An app reading a vault container without the decryption key just sees opaque binary files. For data you want to share openly between apps, standard RDF resources in a regular pod container are still the right tool. The vault is specifically for data you explicitly don’t want to share: private notes, health records, credentials, personal archives.

That said, the 0.2.0 release does take a step toward discoverability with an opt-in RDF sidecar. When enabled, the SDK writes a Turtle document alongside the encrypted files containing filenames, content types, sizes, and timestamps in schema.org terms. It’s stored in plaintext, so backup tools and Solid agents the owner authorizes can index vault contents without needing the encryption key. The payloads themselves stay private.

There is also a key delegation feature that lets multiple authorized apps share access to the same encrypted namespace via ECDH key agreement, without the user re-entering a passphrase each time. That covers the “interoperability between apps the user has explicitly trusted” use case.

So the honest answer is: the vault is not a replacement for open RDF data, and it’s not trying to be. It’s for the subset of your data that you want to keep genuinely private, even from the server operator. Both use cases belong in a healthy Solid ecosystem.

1 Like

Well, yes and no.

In Solid, there are only two types of files: RDF Resources and binary resources. It is true that, when we’re talking about “binary resources”, Solid doesn’t place any constraints on the data. You can store anything (a video, an image, an audio file, or whatever other file you want to store). However, the main data type that Solid apps should use are RDF Resources, because that’s what other applications will understand.

You’re saying “plaintext”, but RDF resources are not just plain text. Your server may be storing the data in plain text (using Turtle, for example). But that’s just an implementation detail, other servers may be storing data in a database.

Of course, there is nothing stopping you as a developer from storing all the data in non-RDF Resources. Like you did for the chat using JSON, or using encrypted blobs here. But as we already discussed in that other thread, that means it’s very unlikely that other apps will interoperate with your data. Which, in my opinion, defeats the whole purpose of Solid. I you just want a private data vault, I’m sure there are better solution out there.

This where we disagree completely, I think that’s a false dichotomy. The main idea of Solid is to decouple apps from data. Which is totally different to sharing data openly or not.

For example, let’s say I have some sensitive health records stored in my POD. I don’t want to share those with anyone, so they’ll have the most restrictive sharing permissions possible. However, I may want to read that data myself using a different app. What you’re achieving with this encrypted approach is that I’ll only be able to read that encrypted data with apps using your POD provider and your Vault SDK.

–

The reason why I think this is an issue is that, in my opinion, this is misleading. Similar to the concerns I raised about Inrupt’s Data Wallet, if you’re advertising that your service uses Solid and saying things like “Solid is a W3C standard. Your pod uses open formats that any compatible app can read. You’re never trapped with a single vendor.” (taken from your landing page), you can’t add features like this that make data effectively useless outside of your platform. In my opinion, that’s the definition of vendor lock-in.

Even worse, you also say “Because it’s based on an open standard, you can move your pod to any compatible host — or even run your own server — and all your apps keep working.”. But as far as I understand it, this Vault SDK is coupled to the functionality in your provider, right? On top of that, it only works for paid accounts. So if I started using your service, but then I decide to move elsewhere (or stop paying the subscription), all the data created with this Vault SDK would be trapped to your service.

Agreed — this is exactly the tension we run into with local-first Solid setups too. With MySolido (a Solid pod that runs entirely on the user’s own PC), we hit the same question: how can a vault for genuinely private data — passports, medical records, credentials — be ‘interoperable’ when its whole purpose is to not be shared? The honest answer is that Solid supports multiple use cases, and forcing everything to be interoperable RDF would break the privacy use case. Open RDF where interoperability helps, encrypted or local storage where privacy matters — both belong in a healthy ecosystem.

1 Like

Hey, it seems like we wrote the reply at the same time :D.

As I said, I disagree with that completely. Though I’m not saying your use-case doesn’t make sense in general, I’m just saying it doesn’t make sense to use Solid to solve it. If you’re foregoing the RDF, all the advantages of Solid disappear. You’d be better off not using Solid at all.

Which doesn’t mean we can’t do local-first or encryption… I have been working on CRDTs myself, and it’s already possible to encrypt data at rest and in transit. What is not possible right now is to implement end-to-end encryption whilst retaining interoperability. I would love to have that, and many people have been asking for this. But I don’t think that can be achieved without doing it at a protocol level.


The vault uses AES-GCM encryption and ECDH key agreement, both standard WebCrypto algorithms with no proprietary dependencies. The key material lives as JSON files on your pod, not in our infrastructure, so if you move your pod or cancel your subscription, your files and your keys move with you. The SDK is open source at pod42/PDPVault-SDK, which means any developer can implement the same delegation protocol and read vault data without going through our platform at all. On the paid account question: yes, vault access is a Pro feature. Sustainable open standards need sustainable businesses behind them, and offering end-to-end encryption as a meaningful paid upgrade is how we fund continued development without resorting to ads or data harvesting. The encryption stays open and portable by design – the premium part is the hosted infrastructure and the convenience layer, not a proprietary lock.

On interoperability specifically, I think the design actually addresses your concern more directly than the original post made clear. The opt-in RDF sidecar writes a plaintext Turtle document alongside the encrypted files with filenames, content types, sizes, and timestamps in schema.org terms, so any authorized Solid app can index and query vault contents without the decryption key. For apps that do need the payload, the delegation system uses standard ECDH key agreement – the user grants access once, and any app implementing the open protocol gets a derived key that works against that vault. It is not “only readable by our SDK.” It is readable by any app that speaks the same open standard, which any developer can implement from the published source. The vault is for data that needs to stay private even from the server operator, which is a different threat model than ACL-based sharing.

The Solid ecosystem has struggled to reach non-technical users precisely because the privacy story has always required them to understand ACLs, WebIDs, and access control policies. Most people do not want to manage that, they just want to know their data cannot be read by anyone they did not explicitly choose or used to train future LLMs. A one-tap approval flow that gives a trusted app access to an encrypted namespace is something a non-technical user can understand and reason about. Every person who signs up for a hosted pod because it comes with real encryption they can explain to a friend is a net win for Solid adoption, and a larger ecosystem is better for everyone building on the standard. Lowering that entry bar is not in tension with the principles here – it is the point.


I think this is where we don’t agree, though maybe it’s just a matter of opinion (I’d like to hear what other people think!).

But in my opinion, these two statements are contradictory. You can’t say that this works for non-technical users, and two paragraphs before you said that in order to reuse the data outside of your platform people “just” have to use your SDK to develop another app.

Even in the age of AI, when it’s easier to make software than ever before, people is not going to be making their own apps for everything. Specially not Solid apps. Even if they were, the point of Solid is to decouple apps from data, so they should be able to use their Solid data with any Solid app.

Let’s tackle a specific example, to see what I mean. Let’s say tomorrow you start offering a recipes manager, and for some people recipes are so sensitive that they want to use the Vault features to encrypt the data. What happens if they want to start seeing your recipes in another app, like Umai? Again, they’re not sharing the recipes with anyone, they are still the same person and just want to see the recipes themselves, just using a different app. Both my app and your app would be Solid apps, on paper. But in practice, a user would notice that logging in with my app, they wouldn’t find any recipes because my app doesn’t understand that encryption.

To me, that’s the problem. I guess since your solution is open source and documented, we cannot say it’s technically vendor lock-in. But in practice, if you need to reimplement all applications to use your Vault SDK, things are not much better for users (specially non technical users).

The recipe example is a good one to think through, and I appreciate you walking through it concretely rather than keeping the debate abstract.

You’re right that a user who stores recipes with vault cannot open them in Umai today, but I think it actually points to a misuse of the tool rather than a flaw in the design. If you care about your recipes enough to encrypt them against the server operator, you have already accepted a constraint: you can only access them from apps you’ve explicitly trusted with decryption. Although if someone is encrypting their recipes, I do hope they’ll invite me to dinner so I can find out why!

More seriously though, vault is not a better way to store general pod data. It’s a different thing entirely, for the subset of data where a user has made a deliberate choice to prioritize privacy over portability. For recipes, health records you want to view across multiple apps, or any data where picking up a new app and having it just work matters, standard pod resources with ACL-based access control are the right answer. You’re right that I should have drawn that line more clearly in the original post.

On the non-technical user framing you’ve identified an issue with how I described it. The honest version of that claim isn’t “this works for non-technical users who want their data to move freely between apps.” It’s narrower: “this gives non-technical users a way to store their most sensitive data with a guarantee that is easy to explain.” Those are different audiences within the same user base, and conflating them was imprecise.

On SDK adoption as practical lock-in: you’re right that today only vault-aware apps can read vault data. The same is true of any open encryption standard, including ones that have become widely adopted, but that’s a bet on ecosystem uptake rather than a guarantee. Publishing the source and keeping the protocol dependency-free and documentable is the attempt to make that bet pay off, not a claim that it already has.

I think we actually agree on more than the thread suggests. The goal here isn’t to replace interoperable RDF data, and I’d welcome collaboration on how vault-style encryption could eventually be addressed at the protocol level rather than the SDK level. That’s a better long-term outcome for everyone.

What I was trying to point out is that even though this may be obvious to us, regular users who are not super familiar with Solid won’t be aware of this trade-off. If they see “Solid”, and they know that Solid is a protocol for data portability, they may be surprised to find out that their data is not actually usable by most Solid Apps.

If they’re not aware of all this nuance, I don’t think they’re making a deliberate choice. The marketing materials and the instructions describing this feature should be clear about this.

Personally, I don’t think there should be a trade-off between privacy and interoperability… but given the current state of the protocol, I would agree this is the only way.

I think we actually agree on more than the thread suggests.

Yes, now that we’ve talked through it I think we’re both in the same page :). If users really are aware of these trade-offs, I actually think this is a very cool feature! And thanks for making it open source and keeping it decoupled from your implementation.