Skip to content

Drakkar-Software/OctoVault

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

144 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

OctoVault

OctoVault

Encrypted knowledge at vault-speed. Pages, boards, search β€” all sealed end-to-end. One codebase. iOS, Android, web, desktop. Built on Starfish.

Note

Reference app & proof of concept β€” shows what real E2EE sync can do. Not production-ready (yet).


Core features

πŸ”’ Real E2EE β€” BIP-39 seed β†’ Ed25519 + Kyber keys in secure storage. Pages, blocks, boards sealed per-space. Server sees ciphertext only.

πŸ“ Notion-grade editing β€” Nested blocks (text, headings, lists, todos, code, callouts). Drag to reorder. CRDT-backed live collaboration, conflict-free.

🎯 Kanban + boards β€” Columns, drag-drop cards, properties (assignee, status, due date). Same CRDT foundation as pages. Instant sync.

🌍 One codebase, all platforms β€” Expo SDK 56 β†’ iOS, Android, web, Electron. No "mobile vs. web" fork.

⚑ Live by default β€” REST pull + SSE firehose. Presence, activity, changes streamed via NATS.

🎨 Design-forward β€” Newsreader (editorial serif) + Spline Sans (clean body). Warm pearl, octopus-ink indigo. Light & dark, one source of truth.

πŸ”‘ No passwords β€” Seed-based. Multi-device pairing via QR + PIN. NIP-07 Nostr sign-in. Hold multiple spaces, switch live.

πŸ“΄ Offline-first β€” Pages & boards served from local cache. App opens & reads instantly, no connection needed.

πŸ” Instant search β€” Full-text across pages, blocks, boards, documents. Real-time, no indexing lag.

What you build with it

Spaces & folders β€” organize by project, area, topic. Per-node access: space (E2EE, all members), invite (E2EE, invited users only), or public (readable by anyone).

Pages β€” Notion-style nested blocks. Text, headings, lists, todos, code, callouts, quotes. Drag to reorder, nest infinitely. Live sync across devices.

Boards β€” Kanban columns + cards. Drag between columns, add properties, filter. CRDT foundation = instant conflict-free sync.

Cross-linking β€” Mention pages, reference documents, @-mention members. Builds a knowledge graph inside your vault.

Rich formatting β€” bold, italic, code, strikethrough, links. All encrypted end-to-end.

Attachments β€” Images, files, media embedded & sealed client-side before upload. Storage path bound into the seal's AAD β€” no hostile swaps.

Real-time collab β€” Multiple devices edit the same page. Edits merge conflict-free. Full history preserved.

Offline + sync β€” WAL/CRDT means concurrent offline edits converge correctly when you reconnect. No merge conflicts.

πŸ”’ Encryption by design

Plaintext lives on your devices only. The server is untrusted β€” stores & relays opaque ciphertext, never holds a key.

Your seed is everything β€” 12-word BIP-39 (128 bits entropy) stretched via Argon2id into your root identity: Ed25519 signing key + Kyber/ML-KEM key-encapsulation pair.

Per-space keyrings β€” Each space has one keyring whose CEK seals all pages, blocks, boards via AEAD (AES-GCM).

Capabilities, not accounts β€” Every request signed by your device key & authorized via scoped cap-cert. No server-side passwords or sessions.

Sealed at rest everywhere β€” Native: keys in OS secure store. Web: seeds sealed under random Vault Master Key, wrapped by PIN + optional WebAuthn passkey.

Full technical model: Encryption model section below.

⚑ Get started in 4 commands

pnpm install
pnpm infra:up          # NATS in Docker
pnpm dev               # Starfish :8787 + Whistlers SSE :8080
pnpm web               # App at localhost:8081

Create your first vault. Done.

Native? pnpm ios Β· pnpm android Β· pnpm desktop


πŸ› οΈ Developer guide

Everything below is the nuts-and-bolts reference: prerequisites, the full dev loop, ports, commands and project layout.

Prerequisites

  • Node.js β‰₯ 20 (tested on 24)
  • pnpm 10 β€” npm i -g pnpm
  • Docker (or OrbStack) β€” for NATS

Install

pnpm install

Dev setup

Three services need to run. Open two terminals:

Terminal 1 β€” infrastructure + backend

pnpm infra:up   # start NATS in Docker (detached)
pnpm dev        # Starfish server :8787 + Whistlers SSE :8080

Terminal 2 β€” frontend

pnpm web        # Expo web :8081
# or
pnpm ios        # Expo iOS simulator
pnpm android    # Expo Android emulator
pnpm desktop    # Electron wrapper

Whistlers restart. pnpm dev starts Whistlers once β€” it does not watch for config changes. If you edit infra/whistlers.config.json or bump the @drakkar.software/whistlers package, kill and re-run pnpm dev.

Ports

Service Port What
Expo / Metro 8081 Mobile/web app (dev)
Starfish server 8787 Sync API + /events SSE proxy
Whistlers 8080 Internal NATS→SSE gateway
NATS 4222 Message bus (Docker)

All commands

Command What
pnpm infra:up Start NATS (Docker, detached)
pnpm infra:down Stop all Docker services
pnpm dev Starfish server + Whistlers (concurrently)
pnpm web Expo web
pnpm ios Expo iOS
pnpm android Expo Android
pnpm desktop Electron wrapper
pnpm typecheck TypeScript check all workspaces
pnpm test Run tests

Structure

apps/
  mobile/    β€” Expo SDK 56 universal app (@octovault/mobile)
  server/    β€” Hono Starfish server (@octovault/server)
  desktop/   β€” Electron wrapper (optional)
packages/
  tsconfig/  β€” shared TypeScript base config

Architecture

The app is built on Starfish, a WAL/CRDT sync engine:

  • Pages & blocks (src/lib/page-model.ts) are pure projections over a WalDocument β€” an RGA (Replicated Growable Array) for block order, per-block char-RGA for text, and LWW (Last-Writer-Wins) registers for properties. All edits are CRDT ops; they merge conflict-free even if concurrent.
  • Boards (src/lib/board-model.ts) use RGA lists for columns and cards, with per-card LWW registers for properties.
  • Live sync happens via REST pull + SSE firehose: a /pull fetches the WAL op-log since your last cursor, and /events streams octovault.object.changed notifications in real time via NATS β†’ Whistlers.
  • The object tree (src/lib/use-objects) stays on Starfish's proven union-merge engine (spaces, pages, folders); WAL backs page and board content only.
  • Crypto is injected into Starfish's transport, signer, and encryptor interfaces (src/lib/starfish/wal/*).

Key files

  • src/lib/starfish/wal/ β€” live wiring of starfish-wal: transport, encryptor, signer, snapshot store.
  • src/lib/page-model.ts / board-model.ts β€” pure CRDT projections + mutations.
  • src/lib/use-page.ts / use-board.ts β€” React hooks owning the openβ†’pullβ†’commit lifecycle.
  • src/components/work/PageView.tsx / BoardView.tsx β€” the editors.
  • src/theme.ts β€” design tokens (single source of truth).

See apps/mobile/CLAUDE.md for full design rules and conventions.

Encryption model

The full encrypted sync layer lives in the Starfish SDK; the app supplies only platform adapters under src/lib/starfish/*. Threat model: the server and transport are untrusted β€” they see ciphertext, signed request envelopes and capability scopes, never plaintext or private keys.

Identity & keys

  • A 12-word BIP-39 mnemonic (128-bit entropy) is the only master secret.
  • Each device holds an Ed25519 keypair (request signing) and a Kyber/ML-KEM keypair (key encapsulation for space keyring recipients).

Authorization: capability certificates

  • No server-side passwords or sessions. Every request is signed by the device Ed25519 key.
  • Access is gated by scoped cap-certs: a device cap and a member cap per joined space. The server authorizes a request only if a presented cap proves the scope.

Document & attachment sealing

  • One keyring per space covers every page and board. Its CEK seals all content with AEAD (AES-GCM) before it leaves the client.
  • Attachments are stored as opaque blobs; pages keep only small references. The blob's storage path is bound into the seal's AAD.
  • Key rotation / epochs: inviting a member rotates the keyring epoch. Members see content from their epoch forward.

Device pairing

  • The existing device seals the bundle with the user PIN (Argon2id β†’ AES-GCM), and publishes it to a public rendezvous keyed by a 16-byte CSPRNG nonce.
  • The QR payload is nonce.rootEdPub. The new device opens the blob with the PIN and pins the bundle to the QR-supplied root pubkey.

At-rest storage

  • Native: keys persist in expo-secure-store (Keychain / Keystore).
  • Web: localStorage holds only an AEAD envelope. All accounts live in one Vault sealed under a random Vault Master Key (VMK) via AES-GCM; the VMK is wrapped by the PIN (Argon2id-stretched) and optionally a WebAuthn passkey PRF secret.

Licensing

OctoVault is MIT-licensed. Starfish and supporting infrastructure are licensed separately β€” refer to their repositories for terms.

Contributing

Contributions welcome. Open an issue first to discuss, or read apps/mobile/CLAUDE.md for guidelines.

Questions? Bugs?


Built with πŸ™ by Drakkar Software.

About

End-to-end-encrypted knowledge management. Built on Starfish sync engine

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors