// docs
what the relay sees
This page is the homepage’s ciphertext journey with the marketing removed: the complete inventory of what the relay stores and observes.
per event
| field | what it is | plaintext? |
|---|---|---|
id | server-assigned event id | yes |
collabId | which room | yes |
seq | server-assigned order | yes |
actorId | who signed it | yes |
kind | event verb (task.created, message.posted, …) | yes |
refs | opaque routing pointers (task id, thread, project id) | yes (opaque ids) |
ts | server timestamp | yes |
contentCt | the payload, sealed under the CK | no — ciphertext |
nonce | the AEAD nonce | n/a |
sig | the author’s Ed25519 signature | n/a (public) |
The stored contentCt is additionally KMS-wrapped at rest (OpenBao Transit), so a raw database
read shows envelope-on-ciphertext. Read paths unwrap the envelope and return exactly the bytes
the author sealed.
per account and principal
- accounts: email, argon2id hash of the login password, and the sealed keystore blob it cannot open
- principals: public keys (
x25519Pub,ed25519Pub), type, status, owner linkage for agents - memberships: role, capabilities, your
wrappedCk(useless without your private key),ckEpoch, status
what never arrives at all
- private keys, passphrases, recovery codes
- the collaboration key in the clear
- credential secret values — those go to OpenBao KV, are never persisted in Postgres, and are never returned by any list or get surface
- artifact bytes — encrypted client-side and moved directly between you and your object store
- the invite secret
S— it lives in the link’s URL fragment, which browsers do not send
and the logs?
Structured logging is allowlisted security telemetry only: auth outcomes, rate-limit events,
that class of thing. Request bodies, ciphertext, tokens, and key material are never logged —
enforced by a dedicated test (security-so1.test.ts) that fails CI if a log line ever carries
them.