Thread

Article header

Clients, Words, and Concepts

The words we use can cause a lot of confusion if the concepts behind them are not clearly understood. Particularly when we use the same words to refer to different concepts. This is certainly the case in the recent arguments about whether Primal is a Nostr client or not.

In theological study we have a saying:

Theology is done at the concept level, not the word level.

What is meant by this is a recognition that people often use the same words to refer to different concepts, and as long as you haven’t defined what you mean by the words you are using, two people using the same word to refer to different concepts will continue to talk past one another and confuse anyone observing their interactions. Rather, we should first ensure that when we use a word, we are both understanding the same concept behind it, or agree to use different words for each concept, at least for the sake of our discussion.

This principle, it seems, must also be applied to Nostr concepts when we discuss them publicly. Specifically, I am talking about the basic building-blocks that are the foundation of the Nostr protocol: keys, notes, clients, and relays. These words refer to concepts, and they have a specific nuance in Nostr that they don’t necessarily have in other contexts.

Keys on Nostr aren’t physical pieces of metal, shaped so they will each open a specific lock. Rather, they are cryptograpic key pairs used to sign and verify signatures using unforgeable math.

Notes on Nostr aren’t a string of text scribbled on a small sheet of paper. Rather, they are json text files containing metadata and content (an infinite variety of types of content, I might add), and signed by the author’s private key.

Then there are clients, and that brings us to the current debate about whether Primal in particular qualifies as a Nostr client or not. This is because folks are operating on two different definitions, two different but related concepts, of what constitutes a Nostr client.

The Broad Definition

For most non-technical folks, a Nostr client can be defined very broadly as any app that allows them to post content to Nostr, and to browse and interact with content other users have posted to Nostr. This definition is sufficient for them, because it emphasizes what they experience, and what is important to them.

Exactly how that content is retrieved by the app, or other technical considerations are not in view whatsoever under this very broad concept of what constitutes a Nostr client. Thus, those who operate with this concept are content to refer to Primal as a Nostr client, and they can’t understand how anyone could reasonably state that it is not.

“Of course Primal is a Nostr client!” they protest. “I can go there and see notes from those I follow, explore to find others I might want to follow, post my own notes, and react, comment, and zap other users’ notes. It does everything a client is supposed to do, so there’s no reason not to call it a Nostr client.”

The Narrow Definition

Those who are more technically inclined, who understand the fundamentals of how Nostr works, specifically in order to maintain the principles of free speech, censorship resistance, and assurance that what the user is reading matches what the author actually posted, have a much narrower definition of what constitutes a Nostr client.

Under this definition, a Nostr client must perform the following functions:

  1. It must sign notes as requested by the user, or send signing requests to the user’s preferred signer application.
  2. It must publish the user’s signed notes to the user’s preferred write relays.
  3. It must retrieve notes published by others from either their preferred write relays (outbox model) or the user’s preferred relays or proxies.
  4. It must verify the validity of the signatures attached to notes received to ensure the note’s author signed it with their private key and without any later alteration.

If a Nostr app does not perform all of these functions, it does not meet this narrower and more technical definition of a Nostr client, and those who subscribe to this definition are warranted in saying that Primal is not a Nostr client. It might be a Nostr app of some other kind, but it is not a client. I have seen terms like “lite-client” or “gateway” suggested as alternative terms for apps that don’t perform all of the above listed functions of a Nostr client.

This is not to say that all those who subscribe to the broader definition are non-technical, or don’t understand why clients typically work this way. They simply may not ascribe to the more narrow definition, not believing that all of the above functions are intrinsic to the definition of what constitutes a Nostr client.

Why it Matters

The importance of these functions being done locally by the client is to limit the ways that a user can possibly be censored, or have their speech altered by any centralized entity.

Signing Notes

If notes are not signed locally by the client, or signed by the user’s preferred signer app, but rather sent to a central server that signs on their behalf, then the server has an opportunity to alter what was written by the note author before signing, so that it appears to everyone who later reads that note that it is exactly what the author intended to say.

Note that this is possible for clients that have your private key to do locally, too, but it is much more difficult to do it selectively. This is also why it is important to stick with open-source apps where it is possible to verify the code that is running on your device.

Using remote signers that are on someone else’s server, rather than running on your own device, also has this danger. You are trusting them not to alter the unsigned note before signing it.

The other massive issue with using a server to store multiple users’ keys for remote signing is that it becomes a honeypot for identity thieves. Successfully breaching such a server’s security will give them access to a large number of users’ private keys all at once.

Publishing to Relays

If notes are not sent by the client to the user’s selected relays, but rather to a centralized server first, then that server can censor the user’s speech by selectively publishing to relays only what the server operator agrees with. In extreme cases, the server could block all publishing to relays by a particular user, effectively shutting down their speech unless they switch to a different app.

The server operator can also mask the fact that they aren’t publishing the user’s notes by making it look like it was published in the UI, and the user is still able to see their own notes, but they never get any interaction from other users, because those notes were never forwarded to their preferred relays.

If you ever suspect such a thing is occurring, though, it is easy to hop onto a client like Jumble that allows you to view a particular relay’s feed, and see if your notes show up there.

Retrieving Notes from Relays

If an app does not retrieve notes from the user’s preferred relays, or the preferred write relays of those they follow, but rather retrieves notes from a central server that in turn retrieves the notes from the relays, then it introduces an opportunity for selective censorship. The server can opt not to forward notes from specific users to the app, or to not forward notes that contain certain topics, opinions, or any other criteria that the server owner specifies.

To be sure, many people can see this as a service, depending on what type of content is being blocked. Most of us would like to not see spam, for instance. Many of us would also like to have filters for adult content, and especially for illegal content like CSAM. So when does this practice cross from being a desirable service to being censorship? When it is not something the user has asked for nor has any ability to configure or turn off, would be my contention.

Server-side content moderation, only possible by requiring the use of a server between the app and the relays hosting the notes, allows for content filtering without the user even knowing it is happening, let alone having any say in how aggressive it is.

Once again, this type of content filtering can be done locally, as well. However, if you are using open source apps, you can verify whether the application does this, and the criteria it uses for it, whereas you cannot do so when the filtering is done server-side. Local content filtering is also more likely to have configuration options the user can turn off or otherwise adjust to their own preference.

Local Signature Verification

If an app does not locally verify the signatures of all notes it receives, then the user is trusting that the server or relay providing those notes did not send forged or altered notes. Notes that claim to be written by an specific npub, but which that author never signed for, or the note they actually signed said something different.

This is a similar problem to that of offloading signing of the user’s notes to a centralized server, except in reverse. Instead of the server being able to impersonate a particular user, or alter the content of their notes before they are published, because that user has entrusted the server with their private key, in this instance the server is able to impersonate any user it wants, but only users of their app will see the fake content.

While something similar could be replicated locally by a client generating and displaying fake content, or altering content it receives before displaying it to the user, this is much less likely to occur, especially if you are using open source clients.

So, What About Primal?

With this context, is it now possible to definitively say whether Primal is a Nostr client? No. It still depends on how you define what is essential to the definition of the term. If you subscribe to the broad definition, then yes, Primal is a Nostr client. However, if you believe apps should only be considered Nostr clients if they perform all of the functions listed in the narrow definition, then Primal is not a Nostr client.

What you call it is far less important than understanding the tradeoffs of using Primal rather than a client that would fit the narrow definition.

The Primal app does sign your notes locally, or using your preferred signer, in the case of using the web app with a NIP-07 signer, or using the Android app with Amber. Your private key, is not being stored by Primal on their server, but is remaining local to your device, even if you aren’t able to use a signer app like Amber, such as on iOS.

The Primal app does publish your notes directly to your preferred relays, if you don’t have the “Enhanced Privacy” setting turned on in the Network Settings. If you turn that on, then your notes go to Primal’s caching server first, and the server forwards them to your relays. Since the default setting is to have this feature turned off, since it is configurable by the user, and since it is trivial to verify whether Primal is actually forwarding your notes to your selected relays, this is a non-issue in my opinion. Moreover, it really does enhance your privacy, since your IP address is then hidden from the relays you post to, though not from Primal. You would get similar protection by simply using a VPN, though, and then even Primal would not see your IP address.

After acknowledging the above, however…

The Primal app does not read from the user’s selected read relays, nor from their follows’ selected write relays. Rather, it only reads from Primal’s caching server. There is no way to change this behavior, other than to change the caching server. There is no setting to make Primal read from your relays instead.

Some might argue that this is fine, because users have the ability to change which caching server they use. Sounds like a solid argument, but I don’t know of any other caching servers that folks can switch to, if they prefer. Nor is it trivial for users to host their own caching server. And even if there are other caching servers they can choose, it just means that server now has the ability to censor what they see without them knowing or being able to configure what is being filtered out.

Finally, the Primal app does not verify signatures locally for the notes it displays to you. Those signatures are verified by the server, which means that you are entirely trusting that the server is sending you only notes with valid signatures, and with exactly the content that was originally published by the note’s author.

So long as you understand these tradeoffs, feel free to call the Primal app whatever you like in casual conversation. In technical discussions, though, it would probably be best to reserve the term “client” to refer to apps that perform all of the functions of a Nostr client outlined above.

Replies (0)

No replies yet. Be the first to leave a comment!