Scenario

Core Concepts

Understand the fundamentals.

The vocabulary you need to read the rest of the docs.

Convergent encryption

Every file is encrypted with a key derived deterministically from its plaintext (HMAC-SHA256 + AES-256-GCM with the nonce derived from the same hash). Property: identical input → identical ciphertext → automatic deduplication across users + retransmission safety.

The trade-off: an attacker who already has a candidate plaintext can verify whether you've stored it. For most threat models (your photos, your documents) that's fine; for "is this person storing X" attacks specifically you'd want random-nonce mode (planned, not shipped).

Replication factor

Each vault has replication_factor: N. The mesh keeps trying to land each block on at least N reliable peers through periodic gossip. RF is achieved per-block, not per-vault — small files don't pay the cost of large ones.

A reliable node is one whose config declares reliable: true. Phones default to false — they help seed but don't count.

Capacity pooling

A vault's usable space is the sum of its trusted nodes' free disk, not one node's. Upload through a node that's full and the new file's blocks are placed on a peer that has room (chosen by free space); that peer becomes the holder. You get "out of space" only when the whole reachable mesh is full. The node you wrote through still lists and serves the file — it fetches the blocks from the holder on demand.

This pools capacity across files. And when a single file is too big for any one node, it's sharded: split into contiguous runs of blocks that are placed on different nodes, so one object can exceed any single disk as long as the mesh holds it collectively. Small files that fit on one node aren't sharded — sharding kicks in only when nothing else fits. Reads gather each shard's blocks from whichever node holds them, transparently. Tune the shard size with node.shard_size_bytes (default 1 GiB; set negative to disable and fall back to "out of space" for oversize files).

Only blocks-mode vaults pool — a vault with a storage_path keeps its plaintext locally as the source of truth, so its writes stay on that node. Tune placement with node.placement_mode (local-first default, or balanced to spread every file across the mesh from the start).

Trusted vs. untrusted

Trust = "does this node have the vault key". Untrusted nodes happily store ciphertext blocks and participate in replication; they never see plaintext. This is what lets a €5/month VPS be redundancy without needing to trust the provider.

Vaults, blocks, hash-chains

  • Vault = a name + a key + a policy (RF, storage path, type).
  • Block = a chunk of ciphertext addressed by SHA-256. Sizes: ≤ 512 KiB for small files, 4 MiB for large.
  • Hash-chain versioning = each new version of a file carries a parent_hash pointer to the previous version. Same file edited on two nodes simultaneously → the mesh detects the fork on next gossip. Whether old versions stay restorable is a per-node decision: a folder-backed node keeps them with keep_history: true (storing real ciphertext blocks alongside the plaintext), bounded by a history_retention policy (keep all / last N versions / last N days / staggered Syncthing-style thinning). So a phone can stream files, a laptop hold a plain copy, and a NAS keep the deep history — all of the same vault.
  • Ignore rules = the folder scanner skips junk and VCS files by default (dotfiles, Thumbs.db, editor scratch) and honours per-vault gitignore-style patterns via ignore_globs or a .holdignore file in the folder.

Mesh topology + gossip

There is no central directory. Every node holds a partial view of the mesh, gossipped via the /meshhold/hello/1.0 protocol. A first handshake brings back every other node currently online — any of them can be your bootstrap on the next reconnect.

Three encryption layers

  1. Swarm key — 256-bit shared secret; without it, nodes can't even open a libp2p connection.
  2. Per-connection Noise session key — fresh on every TCP stream, forward-secret, ChaCha20-Poly1305 AEAD.
  3. Per-vault / chat / tunnel / agent content key — independently shareable; one capability doesn't unlock another.

See the diagram on the home page for the visual.