K eltus
← All projects Case study

DisApp Messenger

Compliance-archived end-to-end encrypted messenger with escrow key recovery — no client-side backdoor.

  • Per-device E2E encryption
  • Air-gapped escrow key recovery
  • Two-role unlock (admin + auditor)
  • Web + Android clients byte-compatible

DisApp solves the messenger problem that secure-by-default products usually duck: regulated organizations need archives, but archives that hold the key online are functionally backdoors. DisApp threads the needle. Every message is encrypted per-device with X25519 ECDH for key exchange, AES-256-GCM for body encryption, and ECDSA-P-256 for signing. In parallel, the same content encryption key is wrapped to an air-gapped escrow public key. Clients never possess the escrow private key — compromising any client doesn't compromise the archive.

Unlocking archived messages requires two-role operational control: an admin and an auditor must both consent through a documented workflow before the escrow key holder decrypts. Neither role can do it alone, and the escrow key itself never touches a network. The architecture is deliberately shaped for a future MLS drop-in; the wire format is already MLS-compatible.

Two clients ship from one wire spec: a React TypeScript SPA using WebCrypto and @noble/curves for browsers, and a Kotlin / Jetpack Compose Android client backed by Android Keystore and BouncyCastle. Both implement the protocol byte-for-byte — keys generated on one device are transparently consumable from the other. The Go backend (chi + pgx + PostgreSQL) is stateless and relays only ciphertext.