Document relay-operator visibility for channel messages (public and private)
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## What I found
Channel content (public or private) is stored and full-text-indexed as plaintext, regardless of the channel's access-control setting:
- `migrations/0001_initial_schema.sql` generates `search_tsv` from plaintext `content` for every kind except `1059`, which is explicitly excluded as "(NIP-17 ciphertext)".
- `NOSTR.md` documents NIP-17 gift-wrap DMs (`kind:1059`) as supported and "not indexed in search", but also notes "NIP-04/NIP-44 not implemented" for broader DM encryption.
- A "private" channel restricts *membership/read access* (NIP-29 access control), but does not change how content is stored: the relay operator can read it the same as a public channel.
So for any relay deployment (including a Block-hosted community), the operator can read all channel content, public or private. Only NIP-17 gift-wrapped 1:1 DMs are actual ciphertext to the relay.
#1185 ("encrypt 2-party DMs end-to-end with a relay-owned latch") shows this gap was already understood: its own description notes "group DMs (3-9) stay plaintext until Phase 2", but it was closed without merging, so the current state on `main` is gift-wrap DMs only.
## Ask
Is this the intended/accepted privacy model, or a gap that should be closed? Either way, it doesn't seem to be written down anywhere as an explicit disclosure. Suggest adding a short, explicit statement to `SECURITY.md` (or `NOSTR.md`) along the lines of: "channel messages, public or private, are plaintext to the relay operator; only NIP-17 DMs are end-to-end encrypted."
## References
- `migrations/0001_initial_schema.sql` (search_tsv generated column)
- `crates/buzz-core/src/kind.rs` (`KIND_GIFT_WRAP = 1059`)
- `crates/buzz-test-client/tests/e2e_nostr_interop.rs` (NIP-17 gift-wrap tests)
- `NOSTR.md`
- `SECURITY.md`
- #1185
Contributor guide
Assessment
This issue has not been assessed yet.