[NKP-0016] Client side pub/sub permission control

This NKP proposes a pub/sub permission control mechanism that can be implemented purely on the client side.

Design Goal

We want to achieve the following goal:

  • each group has an owner
  • owner decides who can join the group (everyone, whitelist, or blacklist)
  • members can be removed by owner from the group
  • only group members can send message to the group

Protocol

Join Group

When client wants to join group name owned by user whose public key is pubkey, client subscribes to topic name.pubkey.

Set/Update Permission

When owner wants to set or update who can join the group, he subscribes with a certain family of identifiers, e.g. __0__.__permission__, __1__.__permission__, __2__.__permission__ …, and put permission control information in the subscribe metadata. He can use { "accept": ["*"] } to allow everyone to join, or { "accept": ["addr1", "addr2", ...] } to accept a list of address (whitelist), or { "reject": ["addr1", "addr2", ...] } to reject a list of address (blacklist). Because of metadata size limit, he might use multiple identifiers to store the permission control list.

Get Permission

When anyone wants to get permission control information of a group name owned by pubkey, he first gets all subscriptions of topic name.pubkey, filter out all subscriptions __0__.__permission__.pubkey, __1__.__permission__.pubkey, __2__.__permission__.pubkey …, and merge metadata of these subscriptions. Then he can compute the permission control information of the group.

Publish Message

When a client wants to publish a message to the group name owned by pubkey, he gets both subscribers of the topic name.pubkey and permitted users of the group. Then he sends message to addresses that are both subscribed to the topic and are permitted to the group.

Receive Message

When a client receives a message from a group, he checks if the sender is in the permitted users of the group. If not, client will discard the message.

Attack Resistant

Malicious clients can try to subscribe to the topic or publish message to group members, but honest clients, as long as follow the protocol, will not send any message to or handle message from malicious clients.

Extension

The above basic protocol can be further extended by storing more information in owner’s subscribe metadata. For example, one can have different permission control for sender and receiver, or add other users as admin, etc.

3 Likes

Rather than topic name topic-name.pubkey, what if the owner was the person that was subscribed to the topic for the longest time in sequence?

Rather than topic name topic-name.pubkey , what if the owner was the person that was subscribed to the topic for the longest time in sequence?

Because subscription history is not stored in global state to prevent state exploding, getting this information requires to go through all block history, which is not possible for nodes with pruned ledger and very inefficient for those who have the full history.

Also, if we choose this way, people will start to subscribe to all common topic names just like what happened to the name service before :joy:

Alright.

I had the idea that once the name service is back online, people could claim channels by having their name to match the topic. Maybe this topic.pubkey is a better idea, so you can’t steal admin rights, but UX-wise, I can see it becoming quite difficult for d-chat, since there will be multiple of the same looking topics.

How about the transactions that this will create? Is the 4-free-tx-per-block thing still a thing, or was that removed when spam stopped? edit: on 2nd thought, it is probably too early to worry about tx count since 99% blocks are empty

In the case of {accept: ['1','2'...]}, should the subscribers even need to subscribe, but instead just send a “please add me” message to the channel owner?

I can see it becoming quite difficult for d-chat, since there will be multiple of the same looking topics

I was thinking that maybe group name can be treated the same as username: display name + the first few hex chars of the pk. But it might not be necessary as lots of IM software I know (Telegram, Wechat, etc) allow multiple groups with the same name and it seems to be not an issue.

Also, in the future it’s probably useful to add avatar function for both group and people (which can be put in the sub metadata) so different group can be differentiated even easier.

In the case of {accept: ['1','2'...]} , should the subscribers even need to subscribe, but instead just send a “please add me” message to the channel owner?

I think we need both. Subscribe means subscriber has the intention to join the group. Without subscribe action, the group owner can add random people to the group and send spams, just like Telegram now.

1 Like