Self-hosted encrypted communication

Private Communication

Encrypted chat, calls, files, and backups in one self-hosted app. Devices keep identity and keys; server only moves encrypted traffic.

Identity
Key-derived
Content
Client encrypted
Runtime
Self-hosted

Architecture guide

Map the stack before you read the details.

Use this guide to jump straight to client code, backend coordination, privacy boundaries, backups, operations, and quality controls.

Backend

Coordination without plaintext access.

Backend validates identity and transport, then coordinates real-time state. It routes presence, queues, calls, and files without reading plaintext.

Signed HTTP routes

APIs verify signatures over method, path, time, body, and identity. Responses are schema-validated before send.

WebSocket challenge-response

Each session starts with signed nonce challenge. After auth, socket carries encrypted messages, receipts, presence, and call signaling.

Redis runtime state

Redis stores presence, public keys, encrypted queues, receipts, push subscriptions, pending calls, sessions, and dashboard counters.

Encrypted attachments

Server validates policy, chunks, hashes, manifests, auth, expiry, and acknowledgements. File bytes arrive already encrypted.

Frontend

The browser is the trust boundary.

Browser owns identity, keys, local data, chat, calls, push, and backups. Backend coordinates delivery, not content.

Client cryptography

ECDH P-256, ECDSA P-256, AES-GCM, fingerprints, and `CryptoKey` private keys.

Local persistence

Dexie and IndexedDB keep keys, peers, messages, previews, attachments, queues, and cached media.

Calls and media

WebRTC calls use TURN credentials, ICE restart, relay fallback, wake lock, and reload recovery.

PWA behavior

Service worker handles precache, push alerts, call and message notifications, transfer reminders, and update activation.

Privacy model

The server helps devices meet. Devices keep the secrets.

Identity comes from cryptographic keys, not usernames or passwords. Messages, files, calls, and backups are protected before infrastructure sees them.

Client side

  • Identity generation and fingerprints
  • Private `CryptoKey` objects
  • Message encryption and decryption
  • Attachment encryption
  • Backup export and restore

Server side

  • Signed request validation
  • WebSocket signaling
  • Encrypted queue delivery
  • Presence and call state
  • Operational health metadata

Never plaintext

  • Private keys
  • Passphrases
  • Message content
  • Call media
  • Attachment bytes

Backups

Portable encrypted recovery with PCBK backups.

Frontend decides what data to export. PCBK Core defines encrypted file format and restore rules.

  1. Prepare

    Select identity, peers, messages, attachments, queues, previews, and media for chosen backup mode.

  2. Encrypt

    Argon2id, HKDF, HMAC, AES-GCM, canonical CBOR, and per-record nonces protect file and records.

  3. Validate

    Restore checks prelude, authenticated header, manifest, record order, payload shape, and rollback behavior.

Infrastructure

A self-hosted stack with clear edge responsibilities.

Nginx owns public edge. Backend owns identity checks, signatures, authorization, and event rules.

Nginx

TLS, static PWA files, API proxying, WebSocket proxying, dashboard serving, and generic throttling.

Redis

Presence, queues, receipts, calls, public keys, push subscriptions, and runtime counters.

Coturn

STUN/TURN traversal for WebRTC calls when direct peer media transport is not available.

Dashboard

Private operational view for sessions, queues, services, system signals, risk, alerts, and recent events.

Quality boundaries

Security-sensitive code has explicit contracts.

Tests target backup restore, rollback, and encrypted storage. Runtime validation keeps route and WebSocket contracts strict.

3 Test areas
2 Backup modes
0 Password accounts
1 Zero-knowledge boundary