Feature: Direct Messages (E2EE Policy-Driven Mailbox) #16

Open
opened 2026-04-26 16:45:38 +00:00 by icub3d · 0 comments
Owner

Migrated from GitHub issue icub3d/decentcom#16
Original Author: @icub3d
Original Date: 2026-04-15T14:15:40Z


Feature: Direct Messages (E2EE Policy-Driven Mailbox)

Overview

Direct messages (DMs) allow two or more users to have private, End-to-End Encrypted (E2EE) conversations. DMs are treated as a temporary "mailbox" rather than a permanent archive, with the server acting as a relay and short-term buffer. Persistence is governed by user-selectable retention policies.

Background

The original design (Issue #16) proposed server-side plaintext storage. This has been refined to a privacy-first model where the server is a "mailbox" for encrypted blobs, supporting multi-device synchronization while ensuring data is purged once delivered.

Requirements

  • End-to-End Encryption: All DM content is encrypted before leaving the client.
  • Multi-Device Support: Messages are deliverable to all registered devices of a user (Ref: docs/design/identity.md).
  • Policy-Driven Retention: Users/Admins can choose how long the server stores encrypted messages.
  • Self-Syncing: Senders can see their own messages on their other devices.
  • Group DMs: Support for 3+ users using a shared Group Key model.
  • ACK-based Purging: The server deletes messages once all target devices have acknowledged receipt (based on policy).

Design: Policy-Driven Mailbox

1. Encryption Strategy

  • Key Exchange: X25519 Diffie-Hellman derived from existing Ed25519 identity keys.
  • Content Encryption: AES-256-GCM.
  • Group Keys: A random symmetric "Group Key" is generated for each conversation. This key is encrypted for each participant's device keys and stored locally on the client.
  • Tauri Core Responsibility: All crypto happens in Rust (Tauri core). React and the Server never see plaintext or keys.

2. Retention Policies

Messages in the pending_dms table are purged according to the chosen policy:

  • Burn on Read: Deleted as soon as all participants' registered devices have sent an ACK.
  • TTL (Time-to-Live): Deleted after a fixed window (e.g., 14 or 30 days), ensuring devices have a chance to sync even if offline for a while.
  • Permanent (Opt-in): Standard persistent storage for users who prioritize history over the "mailbox" model.

3. "Mailbox" Workflow

  1. Send: Client A encrypts message for Group Key. Encrypts Group Key for Client B's devices (if new). Sends blobs to Server.
  2. Buffer: Server stores encrypted blobs in pending_dms with a list of "Target Device IDs".
  3. Fetch: Client B (and Client A's other devices) connect and request "pending" messages.
  4. ACK: Upon successful local storage/decryption, the client sends an ACK(message_id, device_id).
  5. Prune: Server removes the device from the target list. If the list is empty (or TTL expires), the message is deleted.

API / Interface Changes

REST Endpoints

  • POST /api/v1/dms/sync - Fetch pending encrypted blobs and metadata.
  • POST /api/v1/dms/ack - Acknowledge receipt of specific message IDs.
  • POST /api/v1/dms/send - Upload encrypted blobs.
  • GET /api/v1/users/:pubkey/devices - Fetch public device keys for a recipient to perform E2EE.

Gateway Events

  • DM_NOTIFY - Real-time signal that new pending messages are available for fetch.

Task List

Server

  • Implement device_keys storage in User model.
  • Create pending_dms and dm_acks tables.
  • Implement retention policy logic and background pruning worker.
  • Add endpoints for device key management and DM syncing.

Client (Tauri/Rust)

  • Implement X25519 key derivation and AES-GCM encryption.
  • Implement Local Secret Store (SQLite) for Group Keys and Message History.
  • Implement background sync/ACK logic.

Client (React)

  • DM Conversation UI (reusing message components).
  • Retention Policy settings UI.
  • Multi-device status indicators.

Open Questions

  • Initial Sync: How does a brand new device get old Group Keys? (Requires "Key Export" or a secure "Device Pairing" flow). -> Answered: No old sync (Forward-only).
  • Metadata Privacy: Should the server know who is talking to whom, or can we mask participants using "Thread IDs"? (Currently: Server knows participants for delivery routing). -> Answered: Server knows participants.
**Migrated from GitHub issue icub3d/decentcom#16** **Original Author:** @icub3d **Original Date:** 2026-04-15T14:15:40Z --- # Feature: Direct Messages (E2EE Policy-Driven Mailbox) ## Overview Direct messages (DMs) allow two or more users to have private, End-to-End Encrypted (E2EE) conversations. DMs are treated as a temporary "mailbox" rather than a permanent archive, with the server acting as a relay and short-term buffer. Persistence is governed by user-selectable retention policies. ## Background The original design (Issue #16) proposed server-side plaintext storage. This has been refined to a privacy-first model where the server is a "mailbox" for encrypted blobs, supporting multi-device synchronization while ensuring data is purged once delivered. ## Requirements - [ ] **End-to-End Encryption:** All DM content is encrypted before leaving the client. - [ ] **Multi-Device Support:** Messages are deliverable to all registered devices of a user (Ref: `docs/design/identity.md`). - [ ] **Policy-Driven Retention:** Users/Admins can choose how long the server stores encrypted messages. - [ ] **Self-Syncing:** Senders can see their own messages on their other devices. - [ ] **Group DMs:** Support for 3+ users using a shared Group Key model. - [ ] **ACK-based Purging:** The server deletes messages once all target devices have acknowledged receipt (based on policy). ## Design: Policy-Driven Mailbox ### 1. Encryption Strategy - **Key Exchange:** X25519 Diffie-Hellman derived from existing Ed25519 identity keys. - **Content Encryption:** AES-256-GCM. - **Group Keys:** A random symmetric "Group Key" is generated for each conversation. This key is encrypted for each participant's device keys and stored locally on the client. - **Tauri Core Responsibility:** All crypto happens in Rust (Tauri core). React and the Server never see plaintext or keys. ### 2. Retention Policies Messages in the `pending_dms` table are purged according to the chosen policy: - **Burn on Read:** Deleted as soon as all participants' registered devices have sent an `ACK`. - **TTL (Time-to-Live):** Deleted after a fixed window (e.g., 14 or 30 days), ensuring devices have a chance to sync even if offline for a while. - **Permanent (Opt-in):** Standard persistent storage for users who prioritize history over the "mailbox" model. ### 3. "Mailbox" Workflow 1. **Send:** Client A encrypts message for Group Key. Encrypts Group Key for Client B's devices (if new). Sends blobs to Server. 2. **Buffer:** Server stores encrypted blobs in `pending_dms` with a list of "Target Device IDs". 3. **Fetch:** Client B (and Client A's other devices) connect and request "pending" messages. 4. **ACK:** Upon successful local storage/decryption, the client sends an `ACK(message_id, device_id)`. 5. **Prune:** Server removes the device from the target list. If the list is empty (or TTL expires), the message is deleted. ## API / Interface Changes ### REST Endpoints - `POST /api/v1/dms/sync` - Fetch pending encrypted blobs and metadata. - `POST /api/v1/dms/ack` - Acknowledge receipt of specific message IDs. - `POST /api/v1/dms/send` - Upload encrypted blobs. - `GET /api/v1/users/:pubkey/devices` - Fetch public device keys for a recipient to perform E2EE. ### Gateway Events - `DM_NOTIFY` - Real-time signal that new pending messages are available for fetch. ## Task List ### Server - [x] Implement `device_keys` storage in User model. - [x] Create `pending_dms` and `dm_acks` tables. - [x] Implement retention policy logic and background pruning worker. - [x] Add endpoints for device key management and DM syncing. ### Client (Tauri/Rust) - [ ] Implement X25519 key derivation and AES-GCM encryption. - [ ] Implement Local Secret Store (SQLite) for Group Keys and Message History. - [ ] Implement background sync/ACK logic. ### Client (React) - [ ] DM Conversation UI (reusing message components). - [ ] Retention Policy settings UI. - [ ] Multi-device status indicators. ## Open Questions - **Initial Sync:** How does a brand new device get old Group Keys? (Requires "Key Export" or a secure "Device Pairing" flow). -> *Answered: No old sync (Forward-only).* - **Metadata Privacy:** Should the server know who is talking to whom, or can we mask participants using "Thread IDs"? (Currently: Server knows participants for delivery routing). -> *Answered: Server knows participants.*
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
icub3d/decentcom#16
No description provided.