Today marks the biggest release so far in Coracle's history. There have been many good days, like when I introduced Coracle to the nostr telegram group, or when I got my fellowship with FUTO, or when I got my grant from OpenSats, or when I got to speak at Nostrasia. But in terms of realizing the vision I've had for the software - for over two years - today is the day.
Coracle now has private groups.
This means you can now send almost any nostr event over an encrypted channel to the rest of the group's members. This is substantially different from group chats, in that it uses rotating shared keys to provide weak forward secrecy, better scaling, and dynamic member access. This more closely approximates one of the most popular social media products in existence - The Nostr is now a direct competitor of The Facebook.
I built this for my community. I wanted something "good enough" to entice people to leave the advertising-fueled surveillance honeypot that is Facebook. In order to work, it needed to at least support notes, events, and marketplace listings. Although support is still quite basic, Coracle has checked all three of these boxes.
Before I get into the details though, it's important to mention that these groups should not be considered "private" any more than Facebook groups or Mastodon servers are (although privacy is substantially better). A better analog might be WeChat, which uses encryption with the same set of trade-offs. So don't post anything to private groups that might get you in trouble!
With that said, it's possible to run a highly private group. The backbone of this spec is e2e encryption, but relay selection can play an important part in hiding metadata from the rest of the network. If you have a relay you trust to protect notes and not share metadata, your security is significantly increased.
Prior art
Nostr-compatible group products aren't a totally novel thing, as it turns out. In fact draft NIP 112 has been around since June, and is already implemented in ArcadeCity. So why am I creating a new standard? I'l get into the positive benefits of my approach more below, but the quick answers are:
- The new encryption standard is going to break compatibility anyway. If we can end up with a better spec, now is the time.
- ArcadeCity development seems to have stalled.
- NIP-72 communities already have a ton of traction, and match what I'm trying to achieve with encrypted channels.
Of course I'm highly indebted to the project, the design of which is still visible in my final design.
Another product that exists to do something similar in a nostr-compatible way is Soapbox by Alex Gleason. This is a great project, particularly since his Mostr project bridges the ActivityPub world and Nostr. ActivityPub works well for highly centralized communities, but the architecture suffers from this centralization too. In particular, not even DMs are e2e encrypted, and just like regular notes are protected only by authentication enforced by servers.
Finally, there's NIP 29, which is fiatjaf's competing groups project. This has some interesting properties, for example the ability to "fork" a group by linking events together. However, similar to ActivityPub it relies exclusively on relays to protect user privacy, and in a fairly non-standard way. You do get to take advantage of nostr's multi-master architecture though, and signatures are also stripped from events in order to discourage propagation through the network.
None of these solutions quite satisfied me, so I built my own.
How it works
One of the coolest things about a NIP 72 community-based group spec is that is supports a spectrum of privacy requirements. A group admin might choose to publish group metadata privately so that it's only visible to the group, publicly so that other people can find the group and ask to join, or leave off a private component entirely.
Likewise, since private groups are backwards-compatible with public communities, it's easy to add a private component to existing groups. This can be useful especially for groups run by a business or content publisher, since public exposure is a good thing but certain group members might have more or less access. This could be used to support a patreon-type model, automating group membership based on subscription tier, for example.
An important aspect of the design that makes automation possible is the concept of a dedicated administration key. By decoupling this key from the original creator of the group, ownership can be shared as simply as sharing the key. This allows multiple admins to manage the group simultaneously either manually or using automations built into the group relays or special purpose bot-clients.
This of course raises the issue of admin access revocation, which isn't possible - that is, until we have a solution for key rotation for normal accounts. Once that's in place, the same process can be used to rotate group admin keys.
In the meantime, it's also trivial to reduce the exposure an admin key gets. You wouldn't generally want to simply paste the key wherever it's needed, but luckily that problem has already been solved as well. Instead of giving every admin or admin bot the key, it's trivial to set up an nsecbunker that authorizes each admin client - and can revoke access as needed.
This level of administration is of course fairly complex, but I think it's important to think through the requirements businesses and other advanced users will eventually impose and anticipate them as we're able, not through over-engineering, but through simple concepts that can be reused.
One other neat feature of this NIP is the definition of invite codes, which are essential for running a private group at any kind of scale. When requesting access to a group, a user can send along a "claim", which can be anything - for example a static invite code, a payment receipt, or an explanation of why they want to join. This claim can be validated by hand by a human, or processed by a bot to instantly admit the new member to the group.
When a new member is admitted to the group, the admin can either share an existing access key with them, or they can rotate the key for the entire group. If relays expire access keys after a certain amount of time, this can create a weak form of forward secrecy, where attackers won't be able to access old content, even if they gain access to the admin key.
Limitations and Future Work
The bar for new nostr clients has risen significantly since I first put Coracle out there. The new groups component is far more mature than Coracle was for much of its early life, but it has its rough edges. Many of these just need to be smoothed out through further UX work, but some are more technical in nature.
- The groups spec relies on NIP 44, which isn't yet available in most signer extensions. That means that unless you log in with your private key (please don't), you won't be able to create or gain access to any private groups.
- Hybrid groups (public groups with a private area) aren't really tested yet, or fully supported in Coracle's UI. It's an open question whether this is even a good idea, since it becomes pretty hard for users to know if they're posting publicly or privately in every context.
- Moderation is not implemented, so if you're creating a public group there is currently no way in Coracle to approve posts. Also, groups created in Coracle don't show up in Satellite for some reason — this is something I'll be working on improving.
- Whether this approach actually scales is another question. It's very hard to build member lists of hundreds of thousands of people, and without a relay helping to filter events, it might become prohibitively expensive to download and analyze all the events posted to a group. We'll see what develops as the design matures and the implementation undergoes stress testing.
Conclusion
Something I like about both nostr and bitcoin is that it empowers the users of the software. The corollary of this of course is that it's important to exercise this power with care - real damage can be done with this group spec, just as real damage can be done to bitcoin holders through low entropy key generation or poor key handling practices. So please, if you're going to implement this spec, communicate clearly with your users its limitations, and encourage them to run their own relays.
Nevertheless, I am stoked to be another 1% closer to my goal of helping my community - and anyone else who uses nostr - to exercise individual sovereignty and protect their freedom and privacy. Let's keep at it.