Advanced

Team vault protocol

Pro-only — multi-user, sharded sync, conflict resolution, tiered permissions.

Architecture overview

Team vaults do not rely on Dropbox / iCloud-style whole-directory sync. Instead, you self-host a CRDT hub and clients subscribe to the shards they care about. That keeps concurrent edits on the same paragraph conflict-free while letting large vaults (10GB+) sync only their hot regions.

The hub is a stateless coordinator: relays ops, persists history, enforces ACLs. The on-disk format is still Markdown + attachments + .kitable tables — if the hub vanishes, every client still has a complete, readable local vault.

It is a textbook local-first design: the network is an optimization, not a dependency. Everyone keeps working offline; reconciliation happens automatically on reconnect.

  • Hub = self-hosted CRDT sync service (Go)
  • Clients = standard Kition desktop or headless
  • Sharding: per-directory; hot dirs get their own sync channel
  • Conflicts: CRDT auto-merges text; metadata uses timestamp + three-way merge
  • Offline: clients keep writing; reconciliation runs on reconnect

Permission model

Permissions are scoped per directory and per role. Roles are pre-defined (owner / editor / commenter / viewer) and customizable. The hub enforces at the op layer — unauthorized writes are rejected and never reach other clients.

Roles compose by inheritance: custom roles can inherits: editor and override specific paths. SSO integrations (OIDC / SAML) map external groups onto roles automatically.

# /etc/kition-hub/acl.yaml
roles:
  engineer:
    inherits: editor
    paths:
      - "engineering/**": editor
      - "finance/**": viewer
  finance:
    inherits: editor
    paths:
      - "finance/**": editor
      - "engineering/**": none

users:
  - email: [email protected]
    role: engineer
  - email: [email protected]
    role: finance
  - email: [email protected]
    role: owner

groups:
  - oidc_claim: "groups"
    mapping:
      "eng-team": engineer
      "fin-team": finance
      "leads": owner

Deploying the hub

The hub ships as a Docker compose stack. For production, keep it inside a VPC, with a reverse proxy (Caddy / nginx) handling TLS and SSO. Postgres stores history; object storage (S3 / R2 / MinIO) holds large attachments.

Minimum production footprint: one hub instance (2 vCPU / 4GB) + one Postgres (managed is fine) + one S3-compatible bucket. Comfortable up to a 50-person team.

services:
  hub:
    image: ghcr.io/kition-ai/vault-hub:latest
    environment:
      DATABASE_URL: postgres://hub:secret@db/hub
      OBJECT_STORE: s3
      S3_BUCKET: kition-vault-prod
      S3_REGION: us-east-1
      ACL_PATH: /etc/kition-hub/acl.yaml
      OIDC_ISSUER: https://auth.acme.com
    volumes:
      - ./acl.yaml:/etc/kition-hub/acl.yaml:ro
    ports: ["7000:7000"]
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_USER: hub
      POSTGRES_DB: hub
    volumes: ["db:/var/lib/postgresql/data"]
volumes: { db: {} }

Connecting a client

# Pair a desktop client to a hub vault
kition vault join \
  --hub https://vault.acme.com \
  --vault team-eng \
  --as [email protected]

# Force a full resync
kition vault sync --vault team-eng --full

# Inspect sync state
kition vault status --vault team-eng

# List shards the client is subscribed to
kition vault shards --vault team-eng

# Subscribe to an additional shard
kition vault shards add --vault team-eng "design/**"

Sync protocol details

The wire protocol is binary frames over WebSocket, in four classes: ops (CRDT ops with vector clocks), presence (cursor and online state), request (history / snapshot fetch), ack (persistence confirmation). Text uses RGA CRDT, metadata uses an LWW map, attachments are content-addressed blob references.

Offline writes accumulate in a local outbox and replay on reconnect. The hub keeps vector clocks per user × shard, so reconciliation is incremental — no full pull.

Operational checklist

  • Daily logical backups of Postgres + cross-region replication for object storage
  • /metrics exposes op rate, active client count, merge-failure counter
  • Hub upgrades are rolling — clients auto-reconnect through the cut
  • Audit log: every op carries user, timestamp, path; ships to your SIEM
  • Revoking a user: edit acl.yaml; the hub hot-reloads and live connections downgrade immediately
  • Snapshot export: kition-hub snapshot --vault team-eng --out /backup/
  • Even if the hub is down, clients keep reading and writing their local vault — that is the local-first guarantee

Related articles

Ready when you are.

Kition is a local-first AI workspace. Markdown documents, structured tables, and an AI agent — running on your own machine, against the model provider you choose.