Concord and NIP-29: Two Designs for Group Chat on Nostr — Magyar összefoglaló¶
Cikk: Concord and NIP-29: Two Designs for Group Chat on Nostr
Szerző: cloud fodder (Nostr: npub10n…ztl5h)
Forrás: njump.to link → nostr.ae
Dátum: 2026. július
Téma: Tech-elemzés két Nostr csoportos chat designról
Bevezetés¶
A cikk a Nostr ökoszisztémában jelenleg létező két csoportos chat designt hasonlítja össze, amelyek különböző alapokra épülnek:
- Concord (CORD-01..07 specifikációk) — minden kulcsra épül, amit szerver soha nem tart; a trust anchor a kulcs-birtoklás
- NIP-29 — a relay a csoport szabályainak enforcing szerve; a trust anchor a relay aláírása
A szerző mindkét designnak ugyanazt a három kérdést teszi fel: 1. Mit lát a relay és a tagok valójában? 2. Hogy néz ki a spam control? 3. Megvalósíthatók-e a push notification-ök?
Egy rövid záró szekció azt vizsgálja, hogy a két válasz hogyan tükrözi egymást, és egy utolsó szekció a Concord legfurcsább következményébe ássa bele magát: a lurker (leselkedő, nem publikáló tag) jelenségébe.
A cikk állítása: a két design near-perfect dual — minden válasz megfordul a kettő között. Egyik sem jobb; mindegyik egy trade-off másik oldalát választja.
Concord (CORD-01..07) — "a kulcs a szerver"¶
Architektúra¶
A Concord egy "private stream" (CORD-01): egy kind 1059 giftwrap-szerű event, de a NIP-59 minta invertálva — fix author, efemer p tag, nem pedig efemer author, fix p tag. A stream author pubkey-e egy community secret-ből van one-way deriválva (group_key(label, secret, id, epoch)), így csak a kulcstartók tudják kiszámolni a címet, és csak ők tudnak érvényes eventet aláírni rajta.
Minden csatorna, a control plane és a guestbook egy-egy saját stream address; ezek csak epoch bump-nál (eltávolítás) rotálódnak. Az encryptionön belül minden üzenet a szerző valódi npub aláírásával van lezárva.
A trust anchor a kulcs-birtoklás, amit minden kliens ellenőriz.
1. Mit lát a relay?¶
A relay többet lát, mint "csak zaj" — ez a nyersanyag a rate-limiting-hez és a push notification-ökhöz:
Eventenként:
- A stream pubkey (meaningless label, de stabil egy epoch-ig)
- Az untweaked created_at (CORD-01 szándékosan nem tweakeli az időbélyegeket) → a relay másodperc-pontos időzítést kap minden üzenetről
- A ciphertext méret (NIP-44 padding durva; a hosszú üzenetek megkülönböztethetők az "ok"-tól)
- Egy random efemer p tag (semmi)
Események és kapcsolatok között:
- Per-csatorna forgalom és ritmus (message counts, burst patterns, active hours, kb. csatornaméret)
- Community klaszterezés subscription filtereken át — a kliens egy {"kinds":[1059],"authors":[pk1, pk2, ...]} filtert küld, ami a relay kezébe adja, hogy ezek a címek egy community-hez tartoznak. NIP-42 AUTH-val ez egy valódi npub-hoz köti az address-set-et, anélkül csak IP-hez
- Kb. tagszám a distinct connection-ökből
- Call activity: efemer 21059 presence heartbeat-ok 30 másodpercenként → a relay látja, hogy hívás folyik és kb. hány résztvevővel
A camouflage (NIP-59 giftwrap traffic-be való beleolvadás) strukturálisan törött: a valódi NIP-59 giftwrap-ok friss efemer author-t használnak eventenként, míg a Concord fix author pubkey-t → bármely relay, ami GROUP BY pubkey-t futtat, triválisan azonosítja a Concord stream-et.
Amit a relay valóban NEM lát: tartalom, belső author-ok, taglista, community/csatorna nevek, szerepek, kitiltások, melyik epoch-N address követte az epoch-N-1-et (rotation unlinkability), és — AUTH nélkül — hogy ki kicsoda.
2. Mit látnak a tagok?¶
A kulcsokon belül a transzparencia közel teljes:
- Minden szerző valódi npubja (minden seal a valódi identitással van aláírva). Ez non-repudiable a kulcstartók között: ha a kulcsok kikerülnek, a szerzőség bizonyítható. A Concord nem "deniable messaging" design
- Teljes taglista (Guestbook joins/leaves/kicks + "observably present" author-ok)
- Teljes audit log (edition chains — minden ban, kick, grant, rename, örökre, aláírva)
- A teljes banlist plain npub array-ként
- Invite attribution (a Join magával hordozhatja, melyik link (és kié) hozta a joiner-t)
- Rekey inclusion (a tagok kiszámíthatják fellow tagok rekey locator-ait)
- Presence, typing, call participation SFU identity-kkel
A legfontosabb member-side metadata tény negatív: a lurkerek láthatatlanok. A tagság kulcs-birtoklás, nincs enforced lista, és az "observation" csak a publikálókat kapja el. Bárki, aki valaha kapott meghívót, csendben olvashat mindent egy rekey-ig, amiből kimarad — és a protokoll ezt nem tudja detektálni.
3. Spam és relay-side rate limiting¶
A spec pozíciója (CORD-02 §4): a kulcs deriválás a spam határ — kívülálló nem is tudja kiszámolni a csatorna címét, és nem tud érvényes wrap-et aláírni, így a flooding szigorúan insider probléma, amit moderation-nel kell megoldani.
A relay opciói korlátozottak: - Per-member rate limiting lehetetlen (minden event egy külső signing key-t használ) - Per-connection/per-IP write throttle működik (olcsó, privacy-preserving, de rotatable IP-k kijátsszák) - NIP-42 AUTH + per-npub write quota hatékony, de az authed npub nem kötődik a belső authorhoz - Per-stream-pubkey caps — griefing fegyver (egy insider spammer kimeríti a shared budgetet, és a relay throttolja a legitim tagokat) - Paid/allowlisted relay — a reális deployment. A spec amúgy is ~5 stabil, community által választott relay felé tolja a közösségeket
A PoW trükk: a NIP-13 normálisan nonce tag-et igényel, amit a no-outer-tags szabály tilt (Appendix B). De a wrap p tag egy random efemer pubkey, aminek nincs ellenőrzött struktúrája — a kliens addig grindelheti ezt az értéket, amíg az event id vezető nullákat nem kap. PoW-gated writes nulla protokoll-változtatással.
Két gap, amit a moderation story nem zár le: 1. Bannolt tag addig égeti a sávszélességet, amíg a Refounding landol. A Ban client-side display filter, és minden tag letölti + dekódolja a floodot 2. Régi epoch address-ek forever floodable-ok. A removed tag örökre tartja a korábbi epoch kulcsokat
4. Push notifications¶
Nem inherent törött — csak a Signal/Matrix "wake and fetch" formát kell, mert más nem lehetséges.
Push-gateway pattern: a device regisztrálja az address set-jét (a stream pubkey-ket, amiket a device ki tudja számolni) egy push gateway-jel. A gateway feliratkozik a community relay-eire, és minden eventnél opaque ping-et tüzel — legfeljebb {event_id, relay}. A device felébred, letölti, dekódolja lokálsan, alkalmazza a saját logikáját (mention? muted channel? banned author?), és rendereli vagy elnyomja a notification-t.
A privacy cost: a gateway megtudja az address set-edet és az aktivitás időzítését — ami pontosan az a metadata, amit a relay amúgy is tud bármely hosszú subscription-nél.
Három Concord-specifikus friction: 1. Mention filtering nem lehet server-side → 5000 fős community-ben minden üzenet device wake-up, aminek a relevanciáját csak helyi dekódolás után lehet eldönteni 2. Rekey-k csendben törik a regisztrációkat — az epoch bump mozgatja az address-t; a gateway egy halott pubkey-t figyel 3. A bot-as-member ötlet működik: a bot egy npub, ami tartja a kulcsokat, mindent dekódol realtime, és szelektíven push-ol (mentions, kulcsszavak, per-csatorna szabályok). A NIP-46 bunker-style service is megnyithatja a rekey blob-okat. De ez teljes tag trust-wise — a notification bot minden üzenetet olvas
5. Általános megfigyelések a spec-ről¶
Erős pontok:
- Self-certifying community_id (ownership egy hash preimage, unforgeable, serverless)
- Identity/access key split (eltávolítás soha nem törli az identitást)
- Plaintext-seal trükk (kind 20014) — control-plane compaction re-wrap-eli az aláírt edition-öket epoch-okon át
- Frozen byte-exact derivations label registry-vel
- Versenyhelyzetek kezelése (refounding collisions, guestbook clock-skew, tie-grinding bounds, vac block-until-synced authority citation)
Tudatos trade-off-ok: - Nincs forward secrecy vagy post-compromise security egy epoch-on belül (szándékosan MLS ellen trade-elve) - Traffic analysis az elfogadott költség (stabil per-epoch address-ek, untweaked timestamps, subscription-filter grouping) - Nincs owner succession — elveszett nsec esetén a community csak Dissolution-nel hal meg - NIP-44 64KB envelope limitációk: ~500-npub banlist, 50-community list, 400-member snapshot chunks, 120-recipient rekey blobs
NIP-29 — "a relay a szerver"¶
Architektúra¶
A NIP-29 egy rövidebb spec, egyetlen alapválasztásra építve: a relay a szerver. Egy NIP-29 csoport egy szabálykészlet, amit a relay érvényesít egy tetszőleges group id string köré. A felhasználók plaintext, valódi kulccsal aláírt nostr event-eket publikálnak, h tag-gel megnevezve a csoportot; a relay elfogadja vagy elutasítja őket a tagsági állapot alapján.
Ez az állapot moderation event-ekből épül (kinds 9000–9020: put-user, remove-user, delete-event, stb.), amiket a relay validál a szerepek alapján. A relay publikálja a hiteles nézeteket — metadata (39000), admin list (39001), member list (39002) — a saját master kulcsával aláírva. Privacy flagek (private, hidden, restricted, closed) relay-enforced access control-tök.
Nincs encryption sehol — sem at rest, sem end-to-end. A trust anchor a relay szava, a relay kulcsával aláírva.
1. Mit lát a relay?¶
Mindent. Ez nem a design hézaga, hanem a design maga. A relay egy teljes Discord szerver metadata-értelemben:
- Minden tartalom, plaintext, örökre, minden hosztolt csoportban — a "private" csak annyit jelent, hogy a relay szűri a mások általi olvasást, nem hogy a relay nem tud olvasni
- Minden szerző valódi npubja minden üzeneten (normál signed nostr event-ek)
- A csoport teljes social graphja: taglista, admin hierarchia és szerepek, minden join request az opcionális reason text-jével, minden leave, minden invite code és ki váltotta be, minden moderation action az indoklásával
- Call participation valódi identitásokkal: a LiveKit JWT
subrequirement a hex pubkey, és a kind 39004 a relay aktívan publikálja, ki van jelenleg hívásban - A LiveKit szerver (rendszerint ugyanaz az operátor) nézheti és rögzítheti a hívásokat, nem csak a metadata-t
A retroaktív kitettség: a relay subpoena vagy kompromittálása a teljes plaintext archívumot adja minden csoportból, taglistákkal együtt. A private ígéret, nem tulajdonság.
2. Spam és rate limiting¶
Itt fizet a relay-as-server fogadás leginkább:
- Write-time membership enforcement — restricted csoportban a non-member event elutasítódik, mielőtt tárolódna
- Per-identity rate limiting triviális — a relay látja minden event valódi author-ját
- Bans actually enforce — a remove-user (9001) a relay elutasítja a célzott jövőbeli write-jait (a socket-en, nem a kliensben)
- Admission-funnel control — join request-ek (9021) chokepoint, amit a relay teljesen kontrollál (invite codes, pending review, payment required)
Két strukturális caveat: 1. Az enforcement csak annyira jó, mint az operátor — a moderation semantics explicit undefined, relay-internal policy 2. A spam control nem komponálódik fork-ok között — ugyanaz a group id egy másik relay-en más enforcement domain
3. Push notifications¶
Megoldott probléma — a plaintext közvetlen payoff-ja:
- Server-side composition works — a relay (vagy bármely gateway, amit etet) látja a tartalmat, a p-tag mention-öket, a tagságot, a group metadata-t → teljesen komponált, szűrt notification-öket küld, mint a Discord
- Mention filtering, keyword alerts, per-channel mutes, digests: mind server-side, nulla battery cost
A privacy-conscious kliens választhat wake-and-fetch-et opaque ping-gel, de ez opció, nem követelmény.
4. Általános megfigyelések a spec-ről¶
Erős pontok:
- Radikálisan egyszerű — egy kliens implementálhatja egy délután alatt, ordinary event handling-gel
- Üzenetek normál nostr kind-ok (threads, articles, calendars, livestreams mind működnek in-group egy h tag-en át)
- Moderation azonnali és valódi
- Operacionális részletek (late-publication rules, duplicate rejection prefixes, capability probing, invite preauthorization codes)
A fogadás költségei: - A group id self-certifies semmit — "random string of any length", nincs commitment founder-hez vagy kulcshoz. Group identity relay-scoped - A relay master key kompromisszum totális — aki tartja, az aláírja a metadata-t, admin list-et, member list-et, minden group teljes authority layer-jét - Undefined role semantics hurt interop (kind 39003 hirdeti a role neveket, de hogy mit engednek, "specific to each relay and not specified here") - Community portability aspirational — a member list, admin state, history mind egy operátor adatbázisában él - Az AV section az operátorra bízza a media-t — relay-issued JWT-k, valódi pubkey identity-k, relay-published participant list-ek, nincs E2EE requirement a LiveKit-en
Ugyanazok a kérdések, ellentétes válaszok¶
A két design near-perfect dual — minden válasz megfordul:
| Szempont | Concord (kulcs a szerver) | NIP-29 (a relay a szerver) |
|---|---|---|
| Relay lát | Anonim traffic graph (volumes, timing, groupings); soha tartalmat vagy identitást | Mindent: plaintext content, valódi identitások, teljes social graph, hívások |
| Tagok ellenőriznek | Mindent — authority recomputed from owner key, minden kliens által | Semmit önállóan — minden state relay-signed assertion |
| Spam control | Connection throttles, payment, PoW a p-tag grind-en át; valódi enforcement client-side és késik (ban→refounding window) | Write-time membership checks, per-npub limits, bans which enforce at the socket |
| Push | Wake-and-fetch; mention filtering on-device; rekey-k törik a regisztrációkat; keyholder bot a skálázható megoldás | Server komponálja és szűri natívan; nincs rotation, nincs gap |
| Worst-case relay compromise | Metadata | The complete archive |
| Community survives infrastructure | Igen — relay-ek felcserélhető ciphertext bucket-ok | Csak lossy forking-kal, ambiguous identity-vel |
A notification bot a legtisztább tell: Concord-ban a server-side filtering visszahozásához egy trusted, keyholding member-t kell hozzáadni — és az honest deployment per-user, mert egy kommunalis pont olyan plaintext-holding middleman, amit a protokoll törölni akart. NIP-29-ben ez a trusted member mindig is ott volt, az adatbázis formájában — ezért a push triviális, és ezért a private ígéret, nem tulajdonság.
Minden design legnehezebb problémája a másik alapja.
A lurker jelenség — kibontva¶
A természetes ellenvetés a Concord lurker-tulajdonságára: "nem látnád őket egy pubkey listán valahol, és ki hívta meg őket?" — ez két rekordot feltételez: egy membership roster-t és egy invite log-ot. A Concord egyiket sem tartja, és ez strukturális hiány, nem mulasztás.
1. A tagság kulcs-birtoklás, a roster self-reported¶
Nincs admission event. A CORD-02 §7 ezt mondja: "Possession of the keys is membership; the invite is simply how they're handed over." Az egyetlen tagsági rekord a Guestbook, és minden bejegyzés vagy (a) self-signed Join, amit a tag publikálni választ, vagy (b) authorized Kick, vagy (c) refounder's snapshot (ami maga is csak (a) és (b) coalesce-elése az előző epoch-ból).
A "Complete Memberlist" (CORD-02 §5) = Guestbook fold + observably-present authors − banlist. Mindkét input megköveteli, hogy a tag publikáljon valamit. A név túlságosan sokat ígér: a participantok felett teljes, de a kulcstartók felett csak floor.
Bármely enforced roster-nek kell egy gatekeeper, aki credential-eket ellenőriz read time-ban, és az egész design premisszája, hogy ilyen fél nem létezik: a relay nem gate-elheti a read-eket tagságra, mert nem tudja megkülönböztetni a tagokat bárki mástól, és más tagok sem gate-elhetnek, mert a reading csak ciphertext fetching, amit már tartasz a kulcsokkal.
A NIP-29 azért van valódi roster-ekkel, mert van gatekeeper.
2. Az invite trail: három key-handoff path, egyik sem hagy member-visible rekordot¶
A "ki hívta meg" pontosan egy helyen van rögzítve — és az is önkéntes, self-claimed, és nem ellenőrzött:
- Public link (CORD-05 §1–2): a bundle sit bare a relay-en; a beváltás anonim fetch + lokális dekódolás fragment tokennel. Nincs redemption event, nincs regisztráció, nincs counter. A link creator nem tudja, hányan nyitották meg a linkjét. A Registry csak koordinátákat listáz, a tagok látják az ajtót, soha nem azt, ki ment át rajta. Az egyetlen usage signal az opcionális
["invite", creator, label]tag, amit a joiner a Join-jában visszhangoz — és ez a joiner állítása, egyedül a joiner írta alá. A creator nem countersignálja - Direct Invite (CORD-05 §6): person-to-person NIP-59, nem érint community plane-t. "Appears in no Registry" by design. Az inviter privát tudja; más tagok ugyanaz opcionális Join attributionön át tudják meg
- The whisper: bármely keyholder odaadhatja a key material-t bárkinek, out of band. A spec admirably explicit: "No permission gates it, because none could: any keyholder can whisper keys, the ungateable act §2 already accepted as the floor" (CORD-05 §6). Ez az út öli meg bármely invite log reményét elvben
A válasz tehát a "ki hívta meg a lurker-t" kérdésre: legfeljebb egy ember tudja (az, aki whisper-elte a kulcsokat), és a protokoll ezt nem tudja megfigyelni.
Számok, tények, nevek¶
Specifikációk¶
- Concord: CORD-01 (private stream), CORD-02 (membership + control plane), CORD-03 (history pagination), CORD-04 (edition chains, "three removals" decomposition), CORD-05 (invite types, Direct Invite, Registry), CORD-06 (rekey + refounding), CORD-07 (voice broker / SFU)
- NIP-29: moderation event kind-ok 9000–9020, view event kind-ok 39000–39004
Event kind-ok és típusok¶
- 1059 — giftwrap (NIP-59 minta, Concord-ban invertálva)
- 21059 — efemer presence heartbeat (Concord call activity)
- 20014 — plaintext-seal (Concord control-plane compaction kulcsa)
- 13302 / 13303 — Community List / Invite List (real-key signed Concord usage flagek)
- 33301 — Public invite bundle (encrypted content, visible existence)
- 39000 — group metadata
- 39001 — admin list
- 39002 — member list
- 39003 — role names
- 39004 — currently-in-call publication
Konkrét limitek (Concord, NIP-44 64KB envelope-ból)¶
- ~500-npub banlist
- 50-community list
- 400-member snapshot chunks
- 120-recipient rekey blobs
Egyéb technikai paraméterek¶
- 30 másodperces presence heartbeat interval (Concord calls)
- 5 stabil relay community-ként (Concord recommended deployment)
- 4-byte event-id prefix-ek a timeline-reference hack-hez (NIP-29)
- NIP-42 AUTH: a community relay-eken elfogadható trade, public relay-eken nem
Személyek és projektek¶
- Szerző: cloud fodder (
npub10n…ztl5h) - Protocol-ok: NIP-29 (relay-based groups), NIP-42 (AUTH), NIP-44 (encryption), NIP-46 (Nostr Connect / bunker), NIP-59 (gift wrap)
- Összehasonlítási alap: MLS (Messaging Layer Security), Signal, Matrix, Discord, LiveKit, APNs/FCM/UnifiedPush
Kulcsidézetek¶
"Concord derives everything from keys that no server ever holds; NIP-29 makes the relay the enforcer of the group's rules." — cloud fodder
"What the design genuinely protects is content, membership, and which-community — not the fact that an address is a busy group channel. The threat model holds up fine if you read 'camouflage' as 'unlinkable to a community,' but not as 'indistinguishable from DMs.'" — a szerző a Concord camouflage állításáról
"Membership is key possession, there is no enforced list, and 'observation' only catches people who publish. Anyone who ever received an invite can silently read everything until a rekey they're excluded from — and nothing in the protocol can detect them." — a lurker tulajdonságról
"Concord is no worse than NIP-59 here, but it's the opposite of a deniable-messaging design." — a non-repudiable seal-ekről
"A paid/allowlisted relay. Honestly the realistic deployment. The spec already pushes each community toward ~5 stable, community-chosen relays (CORD-02 §6). A community relay that requires payment or a shared write credential solves outsider spam entirely." — a spam control reális deployment-ről
"The clean client-side fix — which the spec doesn't state but should — is to bound old-epoch history queries with until:
: nothing legitimate lands at epoch N after epoch N+1 began, so post-rotation writes to dead addresses are simply never fetched. That one line neutralizes the whole vector and would be a worthwhile addition to CORD-06." — a régi-epoch flood vektorra "A push gateway is metadata-equivalent to a relay; it adds no new class of leak." — a push notification privacy költségéről
"private is a promise, not a property." — a NIP-29 private group-okról
"Each design's hardest problem is the other's foundation." — a near-perfect dual-ról
"Concord has no roster because it has no gatekeeper. NIP-29 has real rosters precisely because it has the gatekeeper." — a lurker jelenség strukturális magyarázata
Összefoglaló készült cloud fodder 5632 szavas "Concord and NIP-29: Two Designs for Group Chat on Nostr" cikkéből (Nostr, 2026. július).