January 31, 2017 Philip Aston

Controlling subscriptions to topics with permissions

There are times when you want to let your end-user clients subscribe to any topic they fancy. And there are times when you want to be able to exert a little control and curation over which topics they are subscribed to. That’s where subscription control and the SELECT_TOPIC and READ_TOPIC permissions come in.

  • Subscription control is the capability that some of our client APIs have, that enables a client (A) to subscribe another client (B) to a topic. A makes the subscription request; B ends up subscribed to the topic.
  • SELECT_TOPIC is the permission that a client needs to be able to select a topic as part of a subscription request. In the scenario just described, A needs this permission.
  • READ_TOPIC is the permission required to receive data from a topic. B needs this permission.

So far, so good? Let’s work this through in a bit more depth:

The client that makes the subscription request, client A… Actually, that’s a boring name. From now on I’ll refer to this client as the Gatekeeper.

OK, the Gatekeeper is the client session that makes the request to subscribe other client sessions to topics in a restricted section of the topic tree. For example, the closed/ branch. To do this, the Gatekeeper needs a role that has the SELECT_TOPIC permission for the closed/ branch.  The Gatekeeper does not necessarily need READ_TOPIC on this branch, as it won’t be subscribing to the topics itself.

Client B – who I’m now going to call the Requester – is a client session that wants to receive data from topics.  The Requester needs READ_TOPIC permission for all branches of the topic tree that it wants to receive data from, including the closed/ branch. The Requester can also subscribe itself to topics that are not in the restricted branch of the topic tree. For that, it needs a role with the READ_TOPIC and SELECT_TOPIC for the unrestricted sections. Let’s have a branch called open/, to illustrate the difference.


The first step in this process is to create the roles that these two client sessions will use. For simplicity, I’m going to call those roles GATEKEEPER and REQUESTER respectively.


  • SELECT_TOPIC permission on the closed/ branch of the topic tree
  • VIEW_SESSION and MODIFY_SESSION permissions that allow it to act on Requester


  • SELECT_TOPIC and READ_TOPIC permission on the open/ branch of the topic tree
  • READ_TOPIC permission on the closed/ branch of the topic tree

Below is a small Node.js client that will connect to your Diffusion Cloud service and set up the required roles, and users. All you need to run this client is a user with the ADMINISTRATOR role – which you can set up from the Diffusion Cloud dashboard – and Node.js installed on your system.

Save this as keymaster.js:

Then run it from the command line using NodeJS:

npm install diffusion
node keymaster.js

This will result in two new users with these roles existing in the system users table on the Diffusion Cloud Dashboard:


The addition of permissions to the TOPIC_CONTROL role, enables the admin user to create topics at open/cats/ and closed/cats/. And that’s what we’ll do now. Let’s use the test client on the Diffusion Cloud Dashboard to create the topics:


And while you’re at it, why not update the topics with a few values.


Requester attempts to subscribe to a topic in the open/ branch of the topic tree (for example, open/cats/) and to a topic in the closed/ branch of the topic tree (for example, closed/cats/).

Save as requester.js

Now run the client:

node requester.js

The first subscription is successful, because Requester has all of the required permissions. The second subscription is not successful; without SELECT_TOPIC permission on the closed/cats/ topic, Requester cannot select this topic for subscription.

Subscribed to topic: open/cats
open/cats updated with value: miaow

Requester is still running. Leave it running with its connection to Diffusion Cloud open so that Gatekeeper can step in.


Enter Gatekeeper to save the day. Gatekeeper can select any topic in the closed/ branch for subscription and, as long as Requester has READ_TOPIC permission for that topic, Gatekeeper can subscribe Requester to the topic.

Save as Gatekeeper.java:

Build and run Gatekeeper, ensuring that an SLF4J binding library (slf4j-simple-1.7.22.jar, for example) and the Diffusion Cloud Java client library (diffusion-client.jar) are available on the build path and class path.

Look across to the terminal running Requester, you should see the following:

Subscribed to topic: closed/cats
closed/cats updated with value: hiss

Requester is now subscribed to the closed/cats/ topic.

But why do it this way?

Why would Gatekeeper subscribe Requester to a topic? Here are a couple of use cases:

Curated Subscriptions

Instead of end users subscribing to topics, your back-end clients decide what end users should be subscribed to based on any number of factors. For example:

  • The end-user client’s session properties. A client session’s $Language property could determine that the end user client is subscribed to topics in that language. For this, the curating client could use the subscribe by filter capability and create a filter query to only target those end users with a certain session property.
  • What topics are relevant at this time. If a big event is happening this weekend, the curating client can decide to subscribe end users to it. And then unsubscribe them later once the event is over and that topic is no longer relevant. For this, the curating client could use a session properties listener to receive session IDs for all connected clients and use the subscription control subscribe capability to subscribe those clients to the currently trending topic.
  • Request messages. Instead of having your end user clients subscribe to topics, have them send a message to the required path instead. On receiving the request message through a message handler, the curating client can then choose whether or not to subscribe the end user to a topic that is bound to the requested path.

In all of these cases, all the end user has to do is set up a way of receiving values for any topic that it becomes subscribed to, for example, a value stream.

User-specific topics

You might want to set up the restricted part of your topic tree as a space where user-specific topics are kept: topics that are only intended for a specific session or principal. To restrict read access to each of these topics individually, would require a massive number of roles. The other solution is the one shown above: to give all end users READ_TOPIC access to this branch of the topic tree, but to give none of them SELECT_TOPIC access.

The back-end client can then set up a session properties listener for new client connections. Every time that an end user client session connects, the back-end client can subscribe that session to a topic in the restricted space that is specific to that session or the principal it uses to connect. All the end-user client has to do is set up a way of receiving values from topics in the restricted branch, for example, a value stream.


That’s it for this overview of using subscription control and the SELECT_TOPIC permission to control access to topics. I hope it was useful.


Enjoy the rich functionality of Diffusion 6.7 as part of your event-driven application.

Quick Start Guide

Step-by-step guide to getting started.

Diffusion Cloud

SaaS offering that focuses on business.

Diffusion On-Premise

A pub-sub platform for real-time applications.