Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

811 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

CipherBox Logo

Privacy-first, zero-knowledge encrypted cloud storage on IPFS


What is CipherBox

CipherBox is a personal cloud storage system where privacy is structural rather than a policy promise. All encryption happens on the client β€” the server never sees plaintext data, file names, or usable keys. Encrypted content lives on IPFS and encrypted metadata on IPNS, so the network β€” not CipherBox's infrastructure β€” is the canonical store: clients verify every record cryptographically, and a vault remains readable and recoverable with the owner's key alone, without any CipherBox service. Keys derive deterministically from a Web3Auth login, so the same user gets the same vault on any device and login method.

You can store, organize, and share files and folders across a web app and a desktop app that mounts the vault as a native drive, with multi-device sync and cryptographic revocation of shared access.

Project status: v2 rewrite

The system is mid-rewrite. v2 is being built on main against the blueprint corpus in blueprint/; v1 is frozen on branch v1 (tag v1-freeze) and receives no changes. v1 was a working technology demonstrator (staging-only, never in production) whose TypeScript/Rust twin-engine architecture and TEE-based republishing are replaced wholesale in v2. main now carries the v2 workspace skeleton, filled in slice by slice against the blueprints β€” when code and blueprint disagree, the blueprints win.

Design at a glance

  • One Rust core. All codec, crypto, and state logic lives in two crates: crates/core (wire formats, sealing, key derivation) and crates/engine (the one stateful brain β€” sync, rotation, grants, trust decisions). Desktop links it natively; the web app runs the same crates as WASM in a worker. One implementation, one set of known-answer tests.
  • Zero-knowledge API. The NestJS API is a thin residual surface: account registry, pin relay, and a grant mailbox. It stores only ciphertext and routes IPFS/IPNS operations; it never serves records and never holds material that could decrypt anything.
  • Seeded key hierarchy with cheap revocation. Keys derive per scope (a derivation domain) from a single seed via a BLAKE3 tree KDF. Sharing a folder anchors a new scope; revoking is an O(1) root cut that mints a fresh seed and a new epoch, with descendants re-sealed lazily by ordinary writes rather than an eager cascade.
  • Verified reads, fail-closed. Every resolved IPNS record passes an adoption gate β€” signature, epoch, and structure checks β€” before the engine trusts it. A gate failure is treated as a trust violation, never as mere staleness.
  • Pull-only sync. Clients poll a focus window over IPNS, cache-first, with an offline operation queue. No push channel in v2.0 (the seam for one is in place).
  • Keyless republishing. IPNS records expire; a republisher module inside the API re-PUTs client-signed records (90-day end-of-life) without ever holding a key β€” v1's hardware-enclave (TEE) republisher is gone.

Tech stack

Component Technology
Core Rust β€” crates/core + crates/engine, compiled natively and to WASM
Crypto XChaCha20-Poly1305 sealing, BLAKE3 tree KDF, X25519 + HPKE wrapping, Ed25519/secp256k1 signing
Web React + TypeScript (apps/web), engine hosted in a worker via packages/client
Desktop Tauri v2 + FUSE mount β€” FUSE-T (macOS), libfuse3 (Linux), WinFsp (Windows)
API NestJS + PostgreSQL
Storage IPFS (Kubo) + IPNS, with self-hosted delegated routing (someguy)
Auth Web3Auth MPC Core Kit β€” email OTP, OAuth, external wallet

Documentation

The normative source of truth for the v2 build lives in this repo:

Document Purpose
CONTEXT.md The v2 ubiquitous language β€” every domain term, defined once
blueprint/core.md Wire formats, crypto, KDF catalog, known-answer tests
blueprint/engine.md The engine β€” seam traits, sync, rotation, adoption gate
blueprint/api.md API residual surface, registry, mailbox, republisher
blueprint/web-client.md WASM hosting, tab leadership, web client
blueprint/desktop.md FS projection, host adapters, Tauri shell
blueprint/testing.md Suite map, CI gates, coverage policy
blueprint/deploy.md Freeze mechanics, release management, staging pipeline

For researchers: the as-built v1 specification corpus, ADRs, and the complete design-decision history behind v2 live in FSM1/cipher-box-next β€” its wayfinder map (issue 1) indexes every decision. The docs/ folder here is v1 legacy and is being rewritten during the build.

Repository layout

The v2 workspace (see the blueprints; apps/desktop and tests/ land with their build phases):

cipher-box/
β”œβ”€β”€ crates/
β”‚   β”œβ”€β”€ core/             # Wire formats, sealing, KDF catalog β€” all crypto lives here
β”‚   β”œβ”€β”€ engine/           # The one stateful engine: sync, rotation, grants, trust
β”‚   β”œβ”€β”€ wasm/             # wasm-bindgen bindings over the engine for the web
β”‚   └── fuse/             # FS projection core + per-OS host adapters
β”œβ”€β”€ packages/
β”‚   └── client/           # Worker hosting for the WASM engine, browser seams, tab leadership
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ web/              # React UI β€” renders engine state, forwards intent
β”‚   β”œβ”€β”€ desktop/          # Tauri v2 shell around the natively linked engine
β”‚   └── api/              # NestJS zero-knowledge API
β”œβ”€β”€ blueprint/            # The normative v2 design corpus
└── tests/                # Cross-cutting suites, incl. the live client↔API contract suite

Getting started

Prerequisites: Node.js 22+, pnpm 10+, Docker, and the Rust toolchain (pinned by rust-toolchain.toml).

Both services read a .env copied from a checked-in template. Those templates are the one place the local stack's configuration is written down; this page does not repeat their contents.

1. Start the infrastructure

docker compose -f docker/docker-compose.yml up -d --wait --wait-timeout 180
pnpm install

That brings up Postgres (5432), Kubo (5001 RPC, 8080 gateway), someguy (8190), and the mock record store (3001). Kubo's RPC is an unauthenticated admin API and the dev compose binds it to all interfaces, so run this stack on a network you trust.

--wait holds until every service's healthcheck passes and exits non-zero if one does not within the timeout, so the migration below cannot race a Postgres still starting.

2. Configure and start the API

cp apps/api/.env.example apps/api/.env

pnpm --filter @cipherbox/api migration:run
pnpm --filter @cipherbox/api dev

The template's defaults match the compose stack, so it runs as copied. Both the server and the migration CLI read apps/api/.env from the package directory, which pnpm --filter sets as the working directory.

Its two secrets are throwaway values for a loopback stack β€” never reuse them in a deployed environment. JWT_SECRET signs access tokens, and anyone holding TEST_LOGIN_SECRET can mint a session for any account outside production.

3. Build and serve the web app

In a second shell:

cp apps/web/.env.example apps/web/.env

pnpm --filter @cipherbox/web dev

Vite reads .env at build time, so rebuild after editing it. The template leaves VITE_READ_ACCELERATOR_URL commented out on purpose: dormant is the content gateway's fail-closed state, and a blank value must land there rather than configuring a gateway whose every request fails.

Which record store the local stack uses

Compose starts two /routing/v1 backends, and a local stack should use mock-ipns-routing on port 3001 β€” what both templates ship, as ROUTING_V1_URL (API republisher) and VITE_ROUTING_ENDPOINTS (web client). It is hermetic and in-memory, so a record published locally resolves immediately and deterministically, and no test vault's IPNS names reach the public network. CI and the web-e2e suite make the same choice.

someguy on 8190 participates in the real accelerated DHT. It is there for staging parity and for deliberately testing public-network propagation; point the two variables above at http://localhost:8190 only when that is what you are testing. Both must name the same backend, or the republisher re-PUTs into a store the client never reads.

What this stack can demonstrate today

The API's write path is live end to end: authenticate and POST /content/upload returns 201 with bytes pinned in the local Kubo.

Interactive login through the web UI needs VITE_WEB3AUTH_CLIENT_ID, VITE_WEB3AUTH_VERIFIER and VITE_GOOGLE_CLIENT_ID, which a clean checkout does not carry β€” the UI boots and renders without them, but a Core Kit session cannot be created. The suites that need an authenticated session use the build-time introspection hook instead; see tests/web-e2e/README.md.

A first folder create does not yet publish, because nothing provisions a fresh account's first vault pointer, so its writes are accepted, rendered pending, and reach no endpoint.

Security model

  • The server never holds plaintext data, file names, or unencrypted keys, and never serves IPNS records β€” clients resolve and verify them against the network.
  • Private keys and seeds are never stored in browser storage or sent to the server.
  • All cryptography is implemented once, in crates/core, with a frozen catalog of key derivations; TypeScript contains no crypto of its own.
  • Sharing wraps scope seeds to recipients with X25519 + HPKE; revocation is cryptographic (key rotation), not access-list bookkeeping.
  • Sensitive material is zeroized after use.

See blueprint/core.md for the primitives and blueprint/engine.md for the trust model.

Acknowledgements

This project is inspired by discussions and planning while working on ChainSafe Files. A massive shout-out to all the colleagues who worked on the original ChainSafe Files project.

License

MIT

About

πŸ”’ Your files. Your keys. Interplanetary.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages