Files
quicproquo/docs/MULTI-AGENT-WORK-PLAN.md
Christian Nennemann 750b794342 DM channels (createChannel), channel authz, security/docs, future improvements
- Add createChannel RPC (node.capnp @18): create 1:1 channel, returns 16-byte channelId
- Store: create_channel(member_a, member_b), get_channel_members(channel_id)
- FileBackedStore: channels.bin; SqlStore: migration 003_channels, schema v4
- channel_ops: handle_create_channel (auth + identity, peerKey 32 bytes)
- Delivery authz: when channel_id.len() == 16, require caller and recipient are channel members (E022/E023)
- Error codes E022 CHANNEL_ACCESS_DENIED, E023 CHANNEL_NOT_FOUND
- SUMMARY: link Certificate lifecycle; security audit, future improvements, multi-agent plan docs
- Certificate lifecycle doc, SECURITY-AUDIT, FUTURE-IMPROVEMENTS, MULTI-AGENT-WORK-PLAN
- Client/core/tls/auth/server main: assorted fixes and updates from review and audit

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-23 22:54:28 +01:00

7.1 KiB

Multi-Agent Work Plan: Sections 1 (Security) + 5 (Features)

This document splits work for Future Improvements §1 (Security and hardening) and §5 (Features and product) between two agents so they can work in parallel with minimal merge conflicts.


Agent A: Security and hardening

Owns: Server auth/OPAQUE, TLS config, core crypto (identity, keypackage, hybrid_kem), docs under docs/src/cryptography/ and TLS/cert docs.

A1. 1.2 CA-signed TLS / certificate lifecycle

  • Files: docs/src/getting-started/ (new or existing), crates/quicnprotochat-server/src/tls.rs (optional env), README.md.
  • Tasks:
    1. Add Certificate lifecycle doc: using CA-issued certs (e.g. Let's Encrypt), cert rotation, OCSP/CRL optional. Recommend pinning for single-server.
    2. Optional: server config or env to prefer CA-signed cert path (e.g. QUICNPROTOCHAT_USE_CA_CERT=1 and read from a different path). Low priority if docs suffice.
  • Deliverable: docs/src/getting-started/certificate-lifecycle.md (or section in running-the-server) + README link.

A2. 1.4 Username enumeration (OPAQUE)

  • Files: crates/quicnprotochat-server/src/node_service/auth_ops.rs, docs/SECURITY-AUDIT.md.
  • Tasks:
    1. Document the risk in SECURITY-AUDIT (already mentioned).
    2. Optional mitigation: ensure get_user_record is always called before ServerLogin::start (already true). If desired, add a constant-time delay or dummy work when user not found so response timing does not leak existence. Keep OPAQUE security unchanged.
  • Deliverable: Doc update; optional small code change in handle_opaque_login_start.

A3. 1.1 M7 — Post-quantum MLS

  • Files: crates/quicnprotochat-core/src/ (new or modified crypto provider), crates/quicnprotochat-core/src/group.rs, crates/quicnprotochat-core/src/hybrid_kem.rs, crates/quicnprotochat-core/src/hybrid_crypto.rs.
  • Tasks:
    1. Implement a custom OpenMlsCryptoProvider (or adapter) that uses hybrid X25519 + ML-KEM-768 for MLS KEM (HPKE layer).
    2. Wire hybrid shared secret derivation (see milestones M7) into the provider.
    3. Run full test suite; ensure M3/M4/M5 tests pass.
  • Deliverable: Hybrid KEM in MLS path; tests green. Large change; coordinate with core crate.

A4. 1.3 Stronger credential binding

  • Files: Docs only for now.
  • Tasks: Add a short Future research subsection or ADR: X.509-based MLS credentials, or Key Transparency for public key binding. No code change in this round.
  • Deliverable: docs/src/roadmap/future-research.md or ADR update.

Agent B: Features and product

Owns: Cap'n Proto schema (node.capnp delivery/channel methods), server storage (Store trait, FileBackedStore, SqlStore), node_service/delivery.rs, node_service/key_ops.rs (if createChannel lives there), client commands for channels.

B1. 5.1 Private 1:1 channels (DM)

  • Files: schemas/node.capnp, crates/quicnprotochat-server/src/storage.rs, crates/quicnprotochat-server/src/sql_store.rs, crates/quicnprotochat-server/src/node_service/delivery.rs, new crates/quicnprotochat-server/src/node_service/channel_ops.rs (or add to delivery), migrations for channels table.
  • Tasks:
    1. Schema: Add createChannel @N (auth :Auth, peerKey :Data) -> (channelId :Data); to node.capnp. Rebuild proto.
    2. Store trait: Add create_channel(&self, member_a: &[u8], member_b: &[u8]) -> Result<Vec<u8>, StorageError>, get_channel_members(&self, channel_id: &[u8]) -> Result<Option<(Vec<u8>, Vec<u8>)>, StorageError>. Implement in FileBackedStore (in-memory map channel_id -> (a, b)) and SqlStore (channels table, unique on sorted (a,b)).
    3. Server: Implement handle_create_channel: auth required, identity required; create channel with (caller_identity, peer_key); return 16-byte channel_id (e.g. UUID).
    4. Delivery authz: When channel_id.len() == 16: call get_channel_members. If Some((a, b)), verify caller identity is one of a/b and recipient_key is the other. If channel not found or authz fails, return E022 (or new code). Legacy: channel_id empty = current behaviour (no channel check).
    5. Config: Optional server flag to require channel authz for non-empty channel_id (default on).
  • Deliverable: createChannel RPC, channel storage, per-channel authz on enqueue/fetch/fetchWait; legacy mode when channel_id empty.
  • Ref: DM channels design.

B2. 5.2 MLS lifecycle (remove, update, proposals)

  • Files: crates/quicnprotochat-core/src/group.rs, client commands that use GroupMember.
  • Tasks:
    1. Add remove_member (by index or identity) and update_credential / rekey using openmls APIs.
    2. Handle incoming MLS proposals (Remove, Update) in receive_message path and apply to group state.
    3. CLI: remove and update subcommands or options.
  • Deliverable: Members can be removed and credentials updated; proposals handled; CLI exposed.
  • Ref: OpenMLS API for MlsGroup::remove_member, MlsGroup::process_pending_proposals, etc.

B3. 5.3 Sealed Sender and 5.4 Traffic analysis

  • Files: Docs; optionally crates/quicnprotochat-server, crates/quicnprotochat-client for padding.
  • Tasks:
    1. Document current sealed_sender behaviour (enqueue without identity binding) and that full “sender in ciphertext” is a future protocol change.
    2. Optional: add optional payload padding (e.g. pad to next 256 bytes) or random delay in client send path for 5.4.
  • Deliverable: Doc update; optional padding/behaviour.

File ownership (avoid conflicts)

Area Agent A Agent B
schemas/node.capnp Add createChannel
crates/quicnprotochat-server/src/node_service/auth_ops.rs 1.4 username enum
crates/quicnprotochat-server/src/node_service/delivery.rs 5.1 channel authz
crates/quicnprotochat-server/src/storage.rs 5.1 Store channel methods
crates/quicnprotochat-server/src/sql_store.rs 5.1 channels table + impl
crates/quicnprotochat-server/src/tls.rs 1.2 optional
crates/quicnprotochat-core/ 1.1 M7, 1.3 doc 5.2 group.rs
docs/ 1.2, 1.3, 1.4, 5.3/5.4 — (or shared)

Shared: docs/, README.md. Prefer non-overlapping files (e.g. A adds certificate-lifecycle.md, B does not edit it).


  1. Both: Sync on schema and Store trait changes so B adds createChannel and channel methods without A touching the same trait.
  2. Agent A: Ship A1 (CA/TLS docs) and A2 (1.4 doc + optional code) first; then A3 (M7) in a follow-up PR/batch.
  3. Agent B: Ship B1 (createChannel + channel authz) first; then B2 (MLS remove/update); then B3/B4 (docs/padding).

Completion checklist

  • A1: CA-signed TLS / certificate lifecycle doc
  • A2: Username enumeration doc and/or mitigation
  • A3: M7 hybrid KEM in MLS provider
  • A4: 1.3 credential binding (docs)
  • B1: createChannel RPC + channel storage + delivery authz
  • B2: MLS remove/update and proposal handling
  • B3/B4: Sealed Sender and traffic analysis (docs + optional padding)