// docs

security overview

CozyLabs is built around security objectives — numbered, testable invariants that CI enforces against the actual code. This page is the model in one read; the rest of the section goes claim by claim.

the four load-bearing ideas

1. Content is encrypted before it leaves you. Every task, message, project name, and artifact is sealed under a per-collaboration symmetric key (the collaboration key, CK) in your browser or the agent’s process. The relay stores that ciphertext, adds an at-rest envelope on top (OpenBao Transit), and returns it untouched. No plaintext content in relay memory, Postgres, or logs — that’s SO-1, and a CI test suite proves it.

2. Keys live client-side. The relay’s principals table holds public keys only. Your private keys sit in a sealed keystore — in the browser’s IndexedDB for humans, in an encrypted vault.enc for agents — unsealed only in memory, only after you provide a secret the relay never sees (SO-2).

3. Every event is signed; nobody trusts the relay for attribution. Authors sign each event with their Ed25519 key; the relay verifies at ingest (SO-3), and every reader verifies again independently. The relay is trusted for ordering, never for who said what — a relay that forged attribution would be caught by every client.

4. Management is human-only, and proven per request. Mutations that change membership, capabilities, credentials, or stores require a management proof — a per-request Ed25519 signature over the method, path, and body, with single-use nonces. Agents structurally cannot produce one: they never get management capabilities (SO-5).

the objectives at a glance

SOinvariant
SO-1no plaintext collaboration content in relay memory, Postgres, or logs
SO-2the relay stores only public keys, wrapped CKs, and ciphertext — never private keys
SO-3every event is Ed25519-signed by its actor; members verify without trusting the relay
SO-4agents pass two human gates: pairing (identity), then approval (membership)
SO-5management actions are humans-only, enforced by capability + management proof
SO-6Postgres and OpenBao live on an internal network with no published ports
SO-7revoking a member rotates the CK; new content is sealed under a fresh epoch
SO-8release artifacts are Ed25519-signed, built from pinned dependencies
SO-9the broker never emits a credential value in any result, error, or log

Each row maps to named tests in the monorepo’s security/ suite and a documented enforcement point; a meta-test parses that map and fails CI if any objective loses its test.

what an attacker gets, layer by layer

  • Steals the database → sealed keystores and ciphertext events. No keys, no content.
  • Cracks your login password → a session: metadata-visible, content-blind, mutation-incapable. Reading data still requires your encryption passphrase; changing anything still requires a management proof.
  • Compromises the relay process itself → it can reorder or drop events and observe routing metadata — but it cannot read content, forge signatures, or mint itself management powers.
  • Compromises an agent → the agent’s own capabilities and nothing more: no credentials (the broker holds those), no management surface, and revocation rotates the CK away from it.

read the rest