Skip to content

Add E2EE chat plumbing to supabase-e2ee (key directory, verification, EncryptedRoom)#91

Merged
AndroidPoet merged 1 commit into
mainfrom
feat/e2ee-chat-plumbing
Jun 27, 2026
Merged

Add E2EE chat plumbing to supabase-e2ee (key directory, verification, EncryptedRoom)#91
AndroidPoet merged 1 commit into
mainfrom
feat/e2ee-chat-plumbing

Conversation

@AndroidPoet

Copy link
Copy Markdown
Owner

Extends the opt-in supabase-e2ee module from a raw crypto box into a full plug-and-play encrypted-chat layer.

What's added

  • KeyDirectorySupabaseKeyDirectory (publish/fetch public keys via a device_keys table) + InMemoryKeyDirectory.
  • Verification (MITM defense)safetyNumber(localPub, peerPub) (order-independent, identical on both sides) + a pluggable TrustStore ledger (TrustLevel/TrustEntry, InMemoryTrustStore).
  • EncryptedRoomopenEncryptedRoom(...) factory → verify-first encrypt-on-send / decrypt-on-receive room over supabase-realtime, with history() and a live messages() flow. Strict requireVerified by default; rejects a changed key as IDENTITY_CHANGED.
  • Migrationsupabase/migrations/20260628_add_e2ee_tables.sql (device_keys + e2ee_messages, RLS + realtime publication).
  • Tests (VerificationTest), regenerated BCV api dump, module README.

Notes

  • Adds supabase-database + supabase-realtime as deps of this opt-in module (a Supabase chat app uses both anyway); the raw crypto API stays usable standalone.
  • Because the shared key is symmetric, both peers decrypt the same rows — including their own (no encrypt-to-self workaround).

Honest caveat

Static ECDH→AES-GCM = no forward secrecy (documented in the README). Sufficient for the "server can't read messages" commercial threat model; not Signal-grade.

Verification

:supabase-e2ee:detekt, apiCheck, and :supabase-e2ee:jvmTest all green (VerificationTest 5 + E2eeTest 4 pass).

… EncryptedRoom

- KeyDirectory (Supabase + in-memory): publish/fetch public keys
- safetyNumber() for out-of-band MITM verification + pluggable TrustStore ledger
- EncryptedRoom: verify-first encrypt-on-send / decrypt-on-receive over realtime,
  with history() and a live messages() flow; strict requireVerified by default
- Migration for device_keys + e2ee_messages (RLS + realtime publication)
- VerificationTest, regenerated BCV api dump, module README

Static ECDH->AES-GCM: no forward secrecy (documented); for 'server can't read'
commercial threat model, not Signal-grade.
@AndroidPoet AndroidPoet merged commit a764ff7 into main Jun 27, 2026
7 checks passed
@AndroidPoet AndroidPoet deleted the feat/e2ee-chat-plumbing branch June 27, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant