Skip to content
 
 

Repository files navigation

Web of Trust

CI npm License: MIT

A decentralized trust infrastructure for real-life communities. People meet in person, verify each other's identity via QR code, and build reputation through attestations over time.

No central server sees your data. Everything is end-to-end encrypted and stored locally.

How it works

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│     VERIFY      │ ──► │   COLLABORATE   │ ──► │     ATTEST      │
│                 │     │                 │     │                 │
│ Confirm identity│     │ Share encrypted │     │ Build reputation│
│ by meeting in   │     │ content (tasks, │     │ through real    │
│ person (QR scan)│     │ calendar, maps) │     │ actions         │
└─────────────────┘     └─────────────────┘     └─────────────────┘

Verification ≠ Trust. Verification only confirms: "This is really that person." Actual trust is built through attestations over time.

Protocol Specification

The protocol is specified in the WoT Spec — an open, standards-based protocol combining W3C Verifiable Credentials, DIDComm v2.1, Ed25519, and ECIES for decentralized identity and trust.

Current version: v0.1.0-draft

Live Demo

  • Demo App: web-of-trust.de/demo
  • CRDT Benchmark: web-of-trust.de/benchmark — measure Yjs vs Automerge on your device
  • Relay: wss://relay.web-of-trust.de
  • Vault: https://vault.web-of-trust.de
  • Profiles: https://profiles.web-of-trust.de

Android App

The demo app also ships as a native Android app (Capacitor), distributed through our own F-Droid repository:

  1. Add the repository in your F-Droid client: https://fdroid.utopia-lab.org/fdroid/repo
  2. Install Web of Trust

Web content updates arrive over-the-air; native updates ship through the repository.

Architecture

7-Adapter System

The system is built on swappable adapters — same interfaces, different implementations. This allows experimenting with different CRDT frameworks, messaging protocols, and storage backends without touching application code.

                     ┌───────────────────┐
                     │  Your App / Demo  │
                     └─────────┬─────────┘
                               │
    ┌──────────────────────────┴──────────────────────────┐
    │  wot-core                                           │
    │  ┌─────────┐ ┌──────────┐ ┌────────┐ ┌───────────┐  │
    │  │ Storage │ │ Reactive │ │ Crypto │ │ Discovery │  │
    │  └─────────┘ └──────────┘ └────────┘ └───────────┘  │
    │   ┌───────────┐ ┌─────────────┐ ┌───────────────┐   │
    │   │ Messaging │ │ Replication │ │ Authorization │   │
    │   └───────────┘ └─────────────┘ └───────────────┘   │
    └──────────────────────────┬──────────────────────────┘
                               │
              ┌────────────────┴────────────────┐
              │ adapter-yjs / adapter-automerge │
              └────────────────┬────────────────┘
                               │
              ┌────────────────┼────────────────┐
              │                │                │
        ┌─────┴─────┐   ┌──────┴─────┐  ┌───────┴───────┐
        │ wot-relay │   │  wot-vault │  │ wot-profiles  │
        └───────────┘   └────────────┘  └───────────────┘
Adapter Purpose Implementation
StorageAdapter Local persistence, CRUD Yjs (default) or Automerge
ReactiveStorageAdapter Live queries, subscriptions Observables on CRDT changes
CryptoAdapter Signing, encryption WebCrypto (Ed25519, X25519, AES-256-GCM)
DiscoveryAdapter Public profile lookup HTTP + offline cache
MessagingAdapter 1:1 message delivery WebSocket Relay (ACK + Outbox)
ReplicationAdapter Encrypted CRDT Spaces Yjs or Automerge + E2EE + GroupKeys
AuthorizationAdapter Capabilities / permissions UCAN-inspired, offline-verifiable

Infrastructure

Three CRDT-agnostic services — they only see encrypted bytes, never plaintext:

Service Transport Purpose
wot-relay WebSocket Real-time sync + delivery ACK
wot-vault HTTP Encrypted backup for new device restore
wot-profiles HTTP Public profile discovery (JWS-signed)

Data is also persisted locally in IndexedDB (CompactStore) for offline access.

CRDT Support

Package CRDT Runtime Notes
adapter-yjs Yjs Pure JavaScript (69KB) Default. Fast on all devices.
adapter-automerge Automerge Rust → WASM (1.7MB) Alternative. Heavier on mobile.

Switch at startup with VITE_CRDT=automerge. Both adapters pass the same end-to-end suites. Try the in-browser benchmark to compare on your device.

Identity

  • BIP39 Mnemonic — 12-word recovery phrase (English wordlist)
  • Ed25519 — Signing (via @noble/ed25519)
  • X25519 — Key agreement (ECDH)
  • did:key — W3C Decentralized Identifier
  • HKDF Master Key — Non-extractable CryptoKey, hardware isolation when available
  • Encrypted seed storage — PBKDF2 (600k iterations) + AES-GCM in IndexedDB

End-to-End Encryption

All data is encrypted before it leaves the device. The relay server only sees ciphertext.

  • Symmetric: AES-256-GCM (CRDT updates, group content)
  • Asymmetric: X25519 ECIES (key exchange, 1:1 messages)
  • Envelope Auth: Ed25519-signed message envelopes
  • Group Keys: Per-space key with generation-based rotation

Three Sharing Patterns

  1. Group Spaces — CRDT-based collaboration (ReplicationAdapter)
  2. Selective Sharing — Item-level encryption keys
  3. 1:1 Delivery — Attestations, verifications via Relay

Getting Started

Prerequisites

  • Node.js 22+
  • pnpm 9+

Development

# Install dependencies
pnpm install

# Start demo app (default: Yjs)
pnpm dev:demo

# Start demo app with Automerge
VITE_CRDT=automerge pnpm dev:demo

# Start landing page
pnpm dev:landing

# Run tests
pnpm test                            # all packages (Vitest)
cd apps/demo && npx playwright test  # browser E2E tests (Playwright)

# Build
pnpm build:core

Monorepo Structure

web-of-trust/
├── packages/
│   ├── wot-core/            # @web_of_trust/core — Core library
│   ├── adapter-yjs/         # @web_of_trust/adapter-yjs — Yjs CRDT adapter (default)
│   ├── adapter-automerge/   # @web_of_trust/adapter-automerge — Automerge CRDT adapter
│   ├── wot-relay/           # WebSocket Relay Server (Node.js, SQLite)
│   ├── wot-vault/           # Encrypted Document Store (HTTP, SQLite)
│   ├── wot-profiles/        # Public Profile Service (HTTP, SQLite, JWS)
│   └── wot-fdroid/          # F-Droid repository (Android distribution)
├── apps/
│   ├── demo/                # Demo App (React 19, i18n, Dark Mode)
│   ├── benchmark/           # CRDT Benchmark (Yjs vs Automerge)
│   └── landing/             # Landing Page
└── docs/                    # Architecture docs & specifications

Packages

Package Description Links
@web_of_trust/core Core library — identity, crypto, adapters, services npm
@web_of_trust/adapter-yjs Yjs CRDT adapter (default) — pure JS, 76x faster on mobile
@web_of_trust/adapter-automerge Automerge CRDT adapter — Rust→WASM
wot-relay WebSocket Relay Server — message forwarding, delivery ACK, SQLite
wot-vault Encrypted Document Store — append-only, capability auth, SQLite
wot-profiles Public Profile Service — JWS verification, REST API, SQLite

Quick Start (Code)

// Core — identity, crypto, messaging (root exports)
import {
  IdentityWorkflow,
  WebCryptoProtocolCryptoAdapter,
  WebCryptoAdapter,
  OutboxMessagingAdapter,
} from '@web_of_trust/core'

// Opt-in browser adapters (subpath exports)
import { IndexedDbIdentitySeedVault } from '@web_of_trust/core/adapters/storage/indexeddb'
import { HttpDiscoveryAdapter } from '@web_of_trust/core/adapters/discovery/http'
import { WebSocketMessagingAdapter } from '@web_of_trust/core/adapters/messaging/websocket'

// Profile publication workflow (replaces the former ProfileService)
import { createProfilePublicationWorkflow } from '@web_of_trust/core/application'

// CRDT adapter — choose one
import { YjsReplicationAdapter } from '@web_of_trust/adapter-yjs'
// or: import { AutomergeReplicationAdapter } from '@web_of_trust/adapter-automerge'

// Create identity with the reference workflow
const workflow = new IdentityWorkflow({
  crypto: new WebCryptoProtocolCryptoAdapter(),
  vault: new IndexedDbIdentitySeedVault(),
})
const { mnemonic, identity } = await workflow.createIdentity({
  passphrase: 'my-passphrase',
  storeSeed: true,
})

console.log(mnemonic)          // 12-word BIP39 mnemonic
console.log(identity.getDid()) // did:key:z6Mk...

Tests

2,400+ automated tests across all packages (Vitest), plus 22 Playwright end-to-end tests covering onboarding, verification, spaces, and multi-relay failover. A dedicated encrypted-sync E2E suite runs against a real relay — with both CRDT adapters (Yjs and Automerge).

Demo App Features

  • Onboarding — Create identity with 12 Magic Words + passphrase
  • Recovery — Restore identity from seed on any device
  • QR Verification — In-person identity verification via camera
  • Contacts — Manage verified contacts
  • Attestations — Attest skills/properties, receive, publish
  • Spaces — Encrypted group collaboration (CRDT)
  • Trust Graph — Interactive visualization of your verified network
  • Profile Sync — JWS-signed profiles published to wot-profiles
  • Public Profile — Viewable without login
  • Multi-Device — Sync via Relay + Vault
  • Offline-First — Local data, offline banner, outbox queue
  • i18n — German + English (per-app system language on Android)
  • Dark Mode — Fully supported
  • Debug Panel — Persistence metrics, relay status, CRDT info

Documentation

Document Description
Current Implementation What's built, what works, architecture decisions
NLNet Application Funding application (NGI Zero Commons Fund)
Adapter Architecture 7-adapter specification (wot-core README)
Sync Architecture How data flows between devices, services, and users
Identity & Keys Key generation, protection, and management
Framework Evaluation 16 frameworks evaluated
Social Recovery Shamir Secret Sharing concept
Threat Model STRIDE analysis
Encryption Protocol E2E encryption design

Related Projects

  • Real Life Stack — Modular app toolkit for local communities, built on Web of Trust

Contributing

We're looking for:

  • Communities who want to try it
  • Feedback on UX and concept
  • Developers who want to build with us

License

MIT

About

Ein wachsendes Netzwerk aus echten Beziehungen. Jede Verbindung basiert auf einer persönlichen Begegnung. Jede Attestation auf einer echten Tat.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages