Browse docs
Docs / Admin & IT / End-to-End Encryption Setup
View as Markdown

End-to-End Encryption Setup

Private projects on Starter and above are encrypted by default with a hub-held key (Security covers the model - Free-plan projects and public projects are stored unencrypted). End-to-end (E2E) encryption is a stronger, opt-in tier: the project key is wrapped to each member's own device keypair and never reaches Swarmfile's servers in plaintext, so the service cannot read your file contents at all.

Plan: Pro and above. E2E is enforced server-side - creating an E2E project on a plan without it is refused with a 402 (upgrade required), so pick the tier on a Pro or Enterprise org.

This page is the operational how-to - how to turn it on, set up recovery, and what to know before you do. For the cryptographic model and what E2E does and doesn't protect, read the E2E section of Security first; the short version is that it's content-only (filenames, folder structure, and sizes stay server-visible so search, ACLs, browse, and quota keep working).

Before you turn it on#

Three things are worth internalizing before you create your first E2E project, because two of them are irreversible:

  • The tier is immutable per project. A project is either managed-key or E2E, chosen at creation and never changed. You can't convert an existing managed project to E2E (the hub has already seen its key) or an E2E project back. To move existing data under E2E, create a new E2E project and migrate into it.
  • git-LFS is unsupported on E2E projects. An LFS request returns a per-object 422 with a clear message: a stock git-lfs client can't hold a per-user key and the hub structurally can't read E2E content, so there's no one to encrypt or decrypt for. Use a managed or unencrypted project for LFS, or keep the asset on the mounted drive.
  • Server-side previews are disabled on E2E content. Thumbnails, video posters, scrubbable proxies, and point-cloud previews are all generated server-side, which an E2E project's server can't do because it can't decrypt. E2E files show a generic icon in the dashboard. This is the single biggest day-to-day cost - see File Previews.
  • "E2E with recovery" is not zero-knowledge-absolute. If you set up an org recovery key (strongly recommended, below), a quorum of your admins can reconstruct a project key. That's a deliberate, enterprise-grade tradeoff - the alternative is that a lost password means permanently lost data. Choose consciously and tell your security reviewer plainly: recovery-enabled E2E means "Swarmfile can't read it, but your own admin quorum can."

We'd suggest piloting on a single non-critical project first: the tier is immutable per project, so a hasty rollout is expensive to walk back.

Step 1 - Set up the org recovery key first#

Do this before creating any E2E project. When you create an E2E project, its key is wrapped to your org recovery key if one already exists at that moment. A project created before the recovery key exists has no recovery wrap - losing every member's device would then mean losing that project's data with no way back. Order matters.

As owner, open the Recovery Key tab in the dashboard (owner-only). Creating a recovery key:

  • Generates an org recovery keypair and splits the private half with Shamir secret sharing into N shares with a t-of-N threshold (the default is 2-of-3). Any t shares can reconstruct it; any t−1 reveal nothing.
  • Returns the share strings exactly once, on creation. They are never retrievable again. The view is print-friendly on purpose.

Distribute the shares to different people and different physical locations - a safe, a vault, an HSM, separate offices. The whole point of the threshold is that no single lost or compromised share exposes anything, and no single person can unilaterally decrypt. Store them the way you'd store the master keys to anything else that matters.

Rotating (creating a new key) or revoking is done from the same tab. Note that rotation applies to projects created afterward - it does not retroactively re-wrap projects created under a previous recovery key. Keep the previous shares: recovery accepts shares from any recovery key the org has created, active or previous, so those old shares are the only way to recover a project that was bootstrapped before the rotation. The dashboard warns about this at the rotate button.

Step 2 - Create an E2E project#

Create a project as usual (Projects → New), and choose the E2E encryption tier instead of the default managed tier. The creation dialog states the tradeoff at the point of choice - previews disabled, recovery via the org key only, immutable after creation. E2E projects carry an E2E badge in the project list so the tier is never ambiguous.

Step 3 - Members enroll automatically#

There's no manual key ceremony for ordinary members. When a member signs in on a machine, the engine enrolls that device: it registers the device's public key with the hub, while the private key is generated on the device and never leaves it. No admin action, no per-device setup screen.

Granting a member access to an E2E project happens client-side: an existing member's client wraps the project key to the new member's public key. The consequence worth knowing is timing - a newly added member sees an E2E project's contents only once another member's client has been online to complete that wrap. Add someone while the rest of the team is offline and their access is pending until someone with a key comes online. A running engine watches for the grant on its own and mounts the drive as soon as it lands - there is nothing to restart - and if that member switches to the project before the wrap is done, the switch waits for it rather than failing. If no grant was ever queued for them (for example a member added through a group), the engine asks the hub to open one the first time it tries to mount, so that wait heals without any manual step. An always-on granter closes this gap so grants don't wait on a human being online - enroll it yourself from the Recovery Key tab's "Granter" section (it needs a recovery key set up first, and reuses the same recovery shares): paste your threshold of shares once, and from then on new members and new devices get their keys automatically, on a five-minute cadence at worst.

If you'd rather not run a granter, or a grant is stuck waiting on one, any member whose own device already has the project's key can clear the queue by hand: open the project's Permissions tab in the web dashboard - a banner lists every pending device grant (who it's for) with a Grant access now button that wraps the key to each waiting device on the spot, and a Dismiss button per grant if it was created in error.

Multiple devices for one person#

A member who works on more than one machine transfers their key between devices directly - a one-time, ten-minute code links a new device to an already-enrolled one and moves the wrapped project keys across, without the private key ever touching the hub. The code is bound to your account: a device signed in as a different account can neither link it nor fetch the moved keys. From the CLI: on the device that already has the project, run swarmfile device-transfer start; on the new device, run swarmfile device-transfer link <code> with the code it printed (see the CLI reference for the full details). The Desktop App's Settings → Add another device panel does the same thing without a terminal - generate a code on one device, type it into the other, and both sides poll and finish automatically once linked. Enrollment on the new device is otherwise the same automatic flow as the first.

Recovering a project key#

If a member is locked out and their access can't be re-granted the ordinary way, an owner recovers the project key from the Recovery Key tab's recover flow: gather a quorum of shares from wherever you distributed them (for a project created before a recovery-key rotation, that is the previous key's share set - its threshold may differ from the active key's), enter them together with the project, and the dashboard reconstructs that project's plaintext key. This is a break-glass procedure - it requires the physical cooperation of your threshold of share-holders by design, and it's the reason the shares are stored apart in the first place.

Sharing E2E content externally#

A share link on an E2E project still works for an external reviewer with no account: the key needed to decrypt travels in the link's URL fragment, which browsers never send to the server, so the hub serves only ciphertext and the recipient's browser decrypts locally. Through the link the hub limits raw-block access to the shared file's own blocks, so a recipient fetches only the file you shared - not the rest of the project. That limit is hub access control, not cryptographic separation: the link carries the project key, so treat sharing as a real trust decision and use expiry/revocation; revocation and per-email blocks stop block retrieval on the recipient's very next request. An access-count cap set on an E2E share through the API is enforced per distinct verified email - each new verified visitor consumes one access. (The deeper key-custody detail is in Security Architecture.) Image and PDF previews work this way; video proxies don't (the server can't transcode what it can't decrypt), consistent with the in-app preview limits above.

When a member is removed#

Removing someone from the org cuts off their access to E2E content within a few seconds: the hub stops serving them blocks and their wrapped project keys, revokes their key wraps, and cancels any key grants still pending for them. The revocation reaches every project in the org, including ones in the trash; a project that doesn't answer is retried until it does, and Settings → Access revocations shows any that are still pending. Their desktop drive stops serving files, clears its local cache of the project, and discards the project key it held. Changes they saved that hadn't finished uploading stay on their computer, still encrypted, and upload if their access is restored. A computer that's offline at the time does this when it next reaches the hub - the org's offline access window, on by default at 7 days, bounds how long that can take.

What removal can't do is recall key material that's already on their device. A member who had access held a project key, and the hub can't reach into a machine to erase anything copied from it. If a departing member's copy of the key is a real concern, rotate the project key (below) so future writes stop using it.

Rotating an E2E project key#

A project owner or admin can rotate an E2E project's key from the Desktop App's Settings → My Devices panel - the project's key-access card - and from the CLI with swarmfile project rotate-key (run it with the project open; it reads the active project off the mount). Rotation mints a fresh key generation and re-wraps it to every current device and the org recovery key, all client-side; the hub only ever stores the wrapped envelopes and never sees the key.

Know what it does and doesn't protect:

  • New content is protected. Every write after the rotation is sealed under the new generation.
  • Existing content is not re-encrypted. Blocks written before the rotation stay under the old generation, so a device that already unwrapped the old key can still decrypt content it already has or can still fetch from the swarm. Treat rotation as "stop using the old key going forward", not "make the old key useless everywhere".
  • Rotation is client-driven. The hub never holds the key, so one of your devices performs it; if an org recovery key is configured, the new generation is wrapped to it too, so recovery keeps working. Only owners and admins can rotate.
  • Other devices keep reading. A device that doesn't yet hold the new generation fetches it on its next check and keeps its old-generation key so existing files still open.

Seeing and revoking a project's devices#

Owners and admins can see which devices hold an E2E project's key. Open the project's Permissions tab in the web dashboard and look under Devices with access. Each device is listed with its name, the person it belongs to, its platform, app version and when it was last seen. It also shows whether it still has access and, if not, why: removed from the organization, revoked by an admin, revoked by its owner, or waiting for a new grant.

Revoke cuts one device off from that one project. The device stops opening the project's files, and the copy cached on it is cleared when it next connects. It doesn't get access back automatically, and the person's other devices aren't affected. You can also revoke a device that has lost access but would be given it again when it next asks (removed from the organization, or waiting for a new grant), so a lost device in those states stays locked out. As with any revocation, anything already copied off the device can't be recalled. To cut a device off from every project at once, its owner can revoke it under Settings → My Devices.

What lives where#

For a regular member, enrollment and key-granting are automatic: they happen in the engine without user action, and there's no Desktop App UI for them (nor anything to configure there). The owner-facing admin - the recovery key, its shares, and the recover flow - lives in the web dashboard only.

A member's own device keys, though, are self-service from the web dashboard, the CLI, and the Desktop App - distinct from the owner-only recovery-key/quorum machinery above, which stays web-only. In the dashboard, Settings → My Devices lists every device you've enrolled and lets you revoke a lost one yourself, no admin needed. From the CLI, swarmfile e2e-key status shows this device's own enrolled key (id, public key) straight from its local cache, no hub round trip; swarmfile e2e-key list audits every device enrolled on your account, and swarmfile e2e-key revoke <id> kills a lost one's access the same way the dashboard does.

Revoking a device takes effect on every E2E project in the org. If the device is online, it's cut off within seconds: its drive stops serving the org's E2E projects, and it discards the project keys it held along with its local cache of their files. If it's offline, the same happens as soon as it reconnects. It's also never granted a project key again, even from a request made on one of your other devices. Revoking a device key doesn't sign that device out, though. Revoking the key can't recall a project key that was copied off the device before you revoked it.

The Desktop App's Settings → Add another device panel walks through the same transfer swarmfile device-transfer does below, without touching a terminal.

Headless/CI identities work differently again: swarmfile api-key create mints a project-scoped API key, and for an E2E-tier project that command is a key-management operation - it generates real E2E key material (a device keypair, project-key wrap) for that key to use, printed once alongside the key itself. swarmfile api-key revoke reverses it, tearing down that identity's key material along with the key. There's still no Desktop App surface for either of these CLI paths.

The bottom line for a security review#

  • Contents are unreadable to Swarmfile; metadata (names, structure, sizes) is not.
  • Recovery is your own admin quorum, not the vendor - and only if you set the recovery key up before creating projects.
  • Previews and server-side proxies are off for E2E content, by necessity.
  • Set-up is irreversible per project; pilot before you commit a flagship project to it.
  • Removing a member revokes their key wraps and stops their access, but can't recall a project key already on their device.
  • An E2E project key can be rotated (client-side, owner/admin) so future writes stop using an old key - but that does not re-encrypt existing content, so a device holding the old key can still read what was written before the rotation.

If E2E is a hard procurement requirement, raise it early and we'll walk your reviewer through the envelope format and the recovery threat model directly.