await client.updateUsersPartial({
users: [
{
id: "james_bond",
set: { role: "special_agent" },
},
],
});Permissions and roles
Every Stream product ships with the same configurable permission system, which allows high resolution control over what users are permitted to do. Each product defines its own resources, actions and grant scopes on top of this shared model.
Getting Started
There are multiple important terms to understand when it comes to permission management. Each permission check comes down to three things:
-
Subject- an actor which attempts to perform a certain Action. It can be represented by a User, or by the user's relationship with a resource, such as a ChannelMember in Chat or a FeedMember or Follower in Feeds -
Resource- the item that the Subject attempts to perform an Action on. Chat resources include Channels, Messages and Attachments; Feeds resources include Feeds and Activities; a User can be a Resource in every product -
Action- the exact action that is being performed. For exampleCreateChannel,AddActivity,DeleteMessage
The purpose of the permission system is to answer the question: is Subject A allowed to perform Action B on Resource C?
Stream provides several concepts which help to control which actions are available to whom:
-
Permission- an object which represents actions a subject is allowed to perform -
Role- assigned to a User, or to a user's relationship with a resource, and used to check their permissions -
Grants- the way permissions are assigned to roles, applicable across the entire application or scoped to a product resource such as a channel type in Chat or a feed visibility in Feeds
Permission checking only happens on client-side calls. Server-side calls allow everything so long as a valid API key and secret are provided.
Role Management
To make it easy to get started, all Stream applications come with several roles already built in with permissions that represent the most common use cases. These roles can be customized if needed, and new roles can be created specific to your application.
Assigning a role to a user is what makes them Subject A in the permissions question. Users have one role which grants them permissions for the entire application. Products add a resource-level role on top: Chat assigns channel roles to channel members, and Feeds assigns roles to feed members and followers.
By default all users have the built-in role user assigned. To change a user's role, update the user:
Changing roles is not allowed client-side. Use server-side SDKs for these operations.
Assigning and updating resource-level roles is documented with each product:
Subject
Subject can be represented by a User or by the user's relationship with a resource: a ChannelMember in Chat, a FeedMember or Follower in Feeds. Both the user-level role and the resource-level role are taken into account when checking permissions.
Built-in roles
These built-in user-level roles exist in every Stream application:
| Role | Level | Description |
|---|---|---|
| user | User | Default user role |
| guest | User | Used for guest users created by server-side endpoints. Guests are short-lived temporary users that could be created without a token |
| anonymous | User | Anonymous users are not allowed to perform any actions that write data. You should treat them as unauthenticated clients |
| admin | User | Role for users that perform administrative tasks with elevated permissions |
Each product adds its own resource-level built-in roles, such as channel_member and channel_moderator in Chat or feed_member and feed_follower in Feeds.
You cannot use user-level roles as resource-level roles and vice versa. This restriction only applies to built-in roles.
Ownership
Some Stream entities have an owner, and ownership can be considered when configuring access permissions. The authenticated user owns itself in every product. Each product defines ownership for its own entities: a Channel or Message is owned by its creator in Chat, and a Feed or Activity is owned by its creator in Feeds.
Using the ownership concept, permissions can be set up so that entity owners are allowed to perform certain actions. For example:
-
Update Own User - allows users to change their own properties (except role and team)
-
Update Own Message - allows message senders to edit their messages in Chat
-
Update Own Activity - allows activity authors to edit their activities in Feeds
Custom Roles
In more sophisticated scenarios custom roles can be used. A Stream application can have up to 25 custom roles. Roles are simple and require only a name to be created. They do nothing until permissions are assigned to the role. To create a new custom role you can use the CreateRole API endpoint:
await client.createRole({
name: "special_agent",
});To delete a previously created role you can use the DeleteRole API endpoint:
await client.deleteRole({
name: "agent_006",
});To delete a role, you must remove all permission grants for that role and make sure that no non-deleted users have this role assigned. Resource-level roles can be deleted without reassigning them first, although some users may lose access where that role was used.
Once you have created a role you can start granting permissions to it. You can also grant or remove permissions for built-in roles.
Granting permissions
Grants attach permissions to roles within a scope. The .app scope exists in every product and applies to operations that occur outside product resources, such as modifying other users or using moderation features. Each product adds its own resource scopes: Chat grants permissions per channel type or per channel, Feeds per feed visibility, and Video per call type.
To list all available permissions you can use the ListPermissions API endpoint:
const { permissions } = await client.listPermissions(); // List of Permission objectsEach permission object contains these fields:
| Field | Type | Description | Example |
|---|---|---|---|
| id | string | Unique permission ID | create-message-owner |
| name | string | Human-readable permission name | Create Message in Owned Channel |
| description | string | Human-readable permission description | Grants action CreateMessage which allows to send a new message, user should own a channel |
| action | string | Action which this permission grants | CreateMessage |
| owner | boolean | If true, Subject should be an owner of the Resource | true |
| same_team | boolean | If true, Subject should be part of the team that the Resource is part of | true |
You can manage .app scope grants using the app settings update endpoint:
await client.updateAppSettings({
grants: {
anonymous: [],
guest: [],
user: ["search-user", "mute-user"],
admin: ["search-user", "mute-user", "ban-user"],
},
});A grants update only changes the roles mentioned in the request. Providing an empty array ([]) as a role's permission list removes all grants for that role, and providing null for the grants field resets the whole scope to default settings. The same semantics apply in the product resource scopes.
UI for configuring permissions
Stream Dashboard provides a user interface to edit permission grants under Roles & Permissions.
Client-side permission checks
API responses for product resources include an own_capabilities field with the actions the current user is allowed to perform on that resource, for example add-activity on a feed. You can use this data to show or hide different parts of the UI based on a user's permissions.
Product permission pages
Resource scopes, capability lists and the full permission tables live with each product: