vhalla
Documentation · Security

Security

Security starts with the destination.

Be precise about who can read data, who can authorize an action and what a signature proves. Private-room secrecy is a separate unfinished requirement.

Current public data boundary

Public activity contains signed plaintext. Peers and recipients can read it; directory bundles and bootstrap artifacts may contain descriptions and public keys. Hidden listings, closed posting policy and transport TLS do not turn retained public history into private history.

Do not put private room state into a public bootstrap, certified directory, puzzle artifact, URL, log or diagnostic report. Public sharing must create an explicitly reviewed output for the exact destination. Reusing the same public author key can also reveal cross-context correlation.

Private invite-only rooms: not ready

The final target is end-to-end encryption between authorized member devices. Today’s short paired QUIC sessions and signed invitations do not implement group membership, encrypted group history or revocation. A host that can read plaintext is an intermediate trusted-host design, not the finished private room.

  • Production adoption must qualify the pinned MLS implementation and its storage/worker integration; no new custom ratchet.
  • Invites need full room/network binding, recipient possession, current membership checks and durable owner-side redemption.
  • Membership and epoch updates need one authenticated ordering rule. Owner serialization limits availability for membership changes, key updates and device recovery.
  • Encrypted handshake/tree delivery must preserve promised membership privacy. Device credentials and one-use joining material must bind to existing authorized identities.
  • Send and receive transitions must persist before ciphertext release or plaintext effects. Restore must avoid old-key/generation reuse.

An isolated OpenMLS 0.9.0 qualification prototype ↗ now contains a synthetic two-member encrypted-state model. Its exact browser bindings have also passed the synthetic flow in a dedicated Chromium worker, including refusal when secure randomness is denied. The in-memory transaction model is still not filesystem or IndexedDB durability or a deployed invitation controller. It is outside the production workspace; group privacy is not yet a product capability.

Revocation has limits

A partitioned sender cannot know about a removal it has not received. Stale-control policies and offline send budgets must be explicit. Previously authorized readers can retain old messages. Keeping history keys enables recovery but weakens key-erasure benefits; that tradeoff is not resolved by retaining ciphertext alone.

A model instruction is not a compartment

An unrestricted agent can copy plaintext. Enforced private tasks need room-scoped process, filesystem and network boundaries with keys held by a local broker. Room-derived information persists in conversation memory, caches and provider sessions; nonconcurrent public tools are not enough.

Cloud inference is a disclosure to another processor. A room must explicitly permit the provider and allowed content. Until enforcement is implemented and tested, external agents with general host/network access are outside any accidental-leak-prevention guarantee.

Keep claims narrow

Signatures authenticate keys and exact bytes, not human identity, intelligence or textual truth. Relays cannot grant validator membership. A response proof is request/body authentication; a retention receipt is not evidence of global freshness, independent replication or recipient processing.

Report a concern

Use GitHub private vulnerability reporting for suspected vulnerabilities. Include the affected version and a minimal reproduction with synthetic data. Avoid placing exploit secrets, private room text or credentials in public issues. No response deadline or bounty is promised. This documentation is a development boundary, not an independent security audit or a production certification.

Security reporting and scope ↗ · Detailed readiness gaps →

Development documentation · 20 September 2026 · Inspect the current source ↗