PubNub portal

How to Securely Moderate Chat and Users with BizOps Workspace

Darryn Campbell on May 21, 2024
How to Securely Moderate Chat and Users with BizOps Workspace

This how-to article is part of a series of articles that discuss PubNub’s data management capabilities, collectively known as BizOps Workspace:

BizOps Workspace is a set of tools that help you manage your application. This article will expand on the previous “How to Monitor and Moderate Conversations with BizOps Workspace” article to show an end-to-end secure chat application with manual moderation capabilities, i.e., the ability to monitor conversations in real-time and mute or ban users.

Although this article can be read standalone, I strongly recommend reading the previous “How to Monitor and Moderate Conversations with BizOps Workspace” article to better understand the background to the concepts discussed here.

What is the Channel Monitor?

The Channel Monitor lets chat moderators watch live previews of conversations happening in real-time across multiple channels. If the moderator spots anything disturbing, such as a misbehaving user or offensive messages, they can act immediately to alleviate the issue.

The moderator has a lot of flexibility for which action they can take:

  • Observe a user without limiting their access rights

  • Edit or Delete the offending message

  • Limit the user's ability to publish messages (mute)

  • Limit the user's ability to read or publish messages (ban)

All of the capabilities under the "Monitor" feature are manual: manually reviewing messages, manually muting users, etc. This article does not discuss automatic moderation.

To use the Channel Monitor, you will need to have several features enabled on your PubNub Keyset, specifically App context and Message persistence at a minimum. For more details, please see the ‘Keyset requirements for the Channel Monitor’ section in the previous article.

What is the PubNub Access Manager?

Developers must guard against users attempting to circumvent their moderation system; this is achieved using the PubNub Access Manager.

The Access Manager allows you to define a set of rules that describe the permissions of the specified user (or users) and what action they can perform on specified resources. For example:

  • User with ID 123 has permission to Read and Write to Channel 456

  • All users whose ID matches the regular expression user-* can read from any channel whose ID matches the regular expression global-*

  • User with ID 123 has permission to Update the Channel metadata (i.e., App Context)

For a full list of permissions, please refer to the documentation at https://www.pubnub.com/docs/general/security/access-control#permissions.

PubNub Access Manager is token-based, and the easiest way to describe it is to walk through the authorization flow as shown in the documentation and provide some additional context of how that flow relates to moderation:

  1. Login attempt. Your client will authenticate against your server to log your users into your application. This is likely done through an identity provider; after this step, your server is confident it is talking to a registered app user and who they are. The client requests a PubNub Access Manager authentication token as part of its initialization.

  2. Permission grant request. The server handles the client’s request for a token by invoking the SDK ‘grantToken()’ API. Some points to note about this API: It can only be called with the PubNub secret key and, therefore, can only be invoked from a server; it is available for all of our server-side SDKs; and this API will accept JSON objects to define the resources and permissions that define the user(s) access.

  3. Token returned. PubNub grants the requested permissions to the requested user(s) and returns an authentication token to the server.

  4. Token passed. Your server then returns the authentication token to the original calling client.

  5. Token set. The client can specify this authentication token during its initialization or at any point during the application’s lifecycle through the setToken() method. Being able to update the token at any point is essential since tokens expire, but a client will also need to request a new token if the Channel Monitor updates their permissions (i.e., they are muted or banned).

  6. Authorized API request. Any subsequent calls to PubNub will now be considered authorized. PubNub will allow or deny any API request based on the permissions granted in step 2 and the client’s token validity.

What Does a Secure Moderation Solution look like?

Toward the end of the previous article, I showed a demo of what muting or banning would look like from the client side. The Chat SDK contains moderation events that tell a client whether or not they have been muted or banned; however, other than updating the UI, that does not prevent the client from continuing to send messages even though they have been muted/banned. To securely mute or ban the client, you must revoke their existing Access Manager permissions and grant them new ones to reflect their new mute or ban status.

Consider the following scenario where a user is muted from the ‘musicals’ channel:

  1. A user can access two channels, ‘movies’ and ‘musicals,’ but the administrator wants to mute them from only the ‘musicals’ channel.

  2. The moderator mutes the user using the Channel Monitor. Under the covers, this is invoking the ‘setRestrictions()’ API

  3. The server application receives the ‘mute’ notice through a moderation event and revokes the user’s existing access token.

  4. The client application receives the ‘mute’ notice associated with the ‘musicals’ channel through a moderation event.

  5. The application updates its UI to prevent sending more messages. The user could work around this UI change by modifying the page’s JavaScript, but any attempt to send messages will fail since their auth token has been revoked.

  6. The application requests a new authentication token from the server, as described in the Access Manager section above. The newly granted token will reflect the user’s new permissions, including only having ‘read’ access to the ‘musicals’ channel.

The previous article described the “Components of a moderation solution” and listed the APIs available to both the client and server using the below graphic. The APIs discussed in the above steps are also shown in this graphic.

The Chat SDK Sample App

The same busy engineering team responsible for developing the Channel Monitor and the Chat SDK has also created a sample application written in React Native that uses the Chat SDK.

The sample shows the SDK's capabilities and best practices for developing a realistic and fully-featured chat app using PubNub. It is open source and part of the same GitHub repository that holds the Chat SDK under /samples/react-native-group-chat.

This application has recently been updated to request tokens from an Access Manager server and to request a new token as the user’s permissions change, i.e., they are banned or muted from channels. This improvement has been made since the previous article was written, so be sure to get the latest source from GitHub. At the time of writing, the most recent git commit ID is ae9dfa0

Securely Muting and Banning Users: Demo using the Sample application

This section describes how to get up and running with our end-to-end demo, showing secure moderation from both the client and server perspectives.

Create a PubNub Keyset

I recommend creating a new PubNub keyset to run this demo as follows:

  1. Log into the Admin Portal and either create a new application or a new keyset within an existing application. If needed, you can find step-by-step instructions at our How to Create Admin Portal Keys.

  2. On the keysets page, enable the following configuration options. You can accept defaults unless otherwise specified:

  • App Context. This stores metadata about your channels and users and is described further in the previous article about 'User and Channel Management'. Also enable User Metadata Events, Channel Metadata Events, and Membership Events

  • Message persistence. This stores your message history with PubNub so the administrator can review and edit conversations.

  • Access Manager. Prevents unauthorized access to data and is required to create a secure moderation solution.

  • Presence. Used to track whether a user is online or offline.

Save your changes.

You will need the Publish Key, Subscribe Key, and Secret Key in the subsequent steps.

Build the Sample application

As described earlier, the Chat SDK Sample app is a cross-platform client app written in React Native using the Expo framework.

Clone and build the sample application, following the instructions given in the application’s readme. In particular, ensure you have the prerequisites installed, including yarn and Node.js. The ReadMe talks about using XCode and iOS, but you can also run the app on an Android emulator. At the time of writing, the most recent git commit ID is ae9dfa0

When providing the Pub/Sub keys, use the keys you generated in the previous step. If you do not include the keys within the .env file, the application will default to some demo keys; you may want to disable this logic at https://github.com/pubnub/js-chat/blob/ae9dfa0/samples/react-native-group-chat/App.tsx#L60 to avoid confusion.

Run the application. The ReadMe will instruct you to run yarn ios, but you can also run yarn android or yarn run start, the latter of which gives you an interactive menu.

When you log in, you should see the following warning in your console:

This is because the client has failed to connect to the Access Manager server, so let’s build it.

Build the Sample Access Manager Server

The Sample Access Manager Server can be found at https://github.com/pubnub/js-chat/tree/master/samples/access-manager-api, this is the same monorepo as the client application discussed previously.

Open the src/chatsdk.service.ts file in the editor of your choice and populate the publishKey, subscribeKey, and secretKey. The publish and subscribe keys must match the ones you used to build the client app, and the secret key is available from the keyset page for the app on the admin portal

From the REPO/samples/access-manager-api directory, run yarn run start to start the Access Manager server, and you should see something like the below:

To see what the Access Manager server is doing, look at app.service.ts. You will see the permission structures generated for the requesting user and the call to chat.sdk.grantToken() to apply these permissions, returning the generated authKey to the calling client.

These are the permissions the demo application requires, but your application will likely need different permissions. You can use this provided ruleset as your starting template, but when creating the Access Manager server for your app, consult https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/permissions to understand exactly what permissions are needed by which Chat SDK features.

Relaunch the client demo app application, and you should now be able to log in without error. You will know everything is successful when you get an ‘Authkey refreshed’ toast.

Initiate a conversation between two clients.

Mute and Ban users using the Channel Monitor

Important: If you have not previously initiated a conversation between two clients, do this now. Channels are created by the demo app dynamically, so they will only display in the Channel Monitor after the chat has started.

Note that any user interface updates shown below, such as the ‘auth key refreshed’ banner or the ‘banned user’ modal, are part of the demo application — your application will display this information to the user through its own UI.

  • Launch the Channel Monitor by logging into the Admin portal and selecting the keyset you used for the Access Manager sample and client application.

  • Go to the BizOps Workspace section in the left navigation panel, and select Channel Monitor. If you do not see the BizOps Workspace section, you almost certainly need to upgrade your PubNub plan, but please contact our support if you have any issues.

  • You will be prompted to select your channels to start moderation. The channel name will be 1:1 user with USER_ID, where USER_ID is the username of the person who initiated the conversation.

  • The channel messages will be displayed in real time, including previous messages, if you have persistence enabled on your keyset.

  • Mute the user by pressing the microphone button next to a message sent by that user. You will see a message on the muted user’s device advising that the auth key has been refreshed. Attempting to send a message as the muted user will display a message dialog saying this is forbidden, though the unmuted user remains unaffected.

  • Unmute the user by pressing the microphone button again. You will see a message on the unmuted user’s device advising you that the auth key has been refreshed and sending messages will now succeed.

  • Ban the user by pressing the ban button next to the message sent by that user and provide a ban reason. The reason is free-form text, so you can provide any relevant information. The auth key will refresh and the user will be returned to the chat selection screen in their app.

Attempting to access the banned channel will show an error to the user:

  • Unban the user by selecting ‘Remove ban’ on the Channel Monitor. The auth key will refresh. The user will be unbanned and can access the chat again.

Summary

Developing any chat application is only the first step. The hardest challenges come after you deploy that app to support your growing user base. BizOps Workspace is a set of tools designed to manage every aspect of your chat application, simplifying your post-launch challenges.

Although this article has focussed on securely muting and banning users, we continue expanding the features of BizOps Workspace. This article has also focused exclusively on the Chat SDK, but the Channel Monitor can also be configured to work with any of our SDKs.

If you need help or support, feel free to reach out to our dedicated support team or email our developer relations team at devrel@pubnub.com