await client.updateAppSettings({
permission_version:"v2",
migrate_permissions_to_v2: true,
})
Migrating from Legacy
Depending on which client-side SDK you use, the custom permissions checking processes may not be implemented yet and could affect user experience. If you use our client SDKs, we recommend waiting to migrate until there is complete front end support, or test this thoroughly in development first. Updates will be posted here as we add more support.
The migration process is pretty straightforward and mostly automated, but you should consider these facts before you pull the trigger:
Make sure backend of your app does not explicitly sets “permission_version” field to “v1” using UpdateApp API endpoint. This will cause your app to rollback to previous version of permission system
There are some permissions properties which should no longer be used on v2 so it is good to understand how you are using them today
“Permissions” field in UpdateChannelType will not affect new permission system. This field is kept for backward compatibility and it allows you to roll back to version 1 in case you changed your mind
Do not use
User.role
,ChannelMember.channel_role
to determine user capabilities. This kind of check is usually fragile and in case of configuration change, UI will not be representative of the new settingsDo not use
ChannelMember.role
as it is displaying inconsistent values. This field is kept for backwards compatibility onlyOption
user_search_disallowed_roles
only works with permissions v1. To control set of users who can perform user search you should use application-level permission grants (.app
scope)If you plan to use custom permissions, make sure your client code does not rely on direct role comparisons. Please see Channel Capabilities page for more info
Prerequisites
In order to use version 2 of permissions system, make sure you use compatible version of SDK
SDK | Minimum version |
---|---|
React | v7.0.0 |
React Native | v4.0.0 |
Angular | v2.2.0 |
Android | v4.27.0 |
iOS | v4.0.0 |
Flutter | v3.4.0 |
Unreal | v1.0.0 |
Unity | v1.0.0 |
iOS and Unreal SDKs don’t support Channel Capabilities yet
We strongly recommend to regularly update your SDK dependencies since they constantly improve user experience, resolve bugs and add support for new features
How to migrate
We provide two options for performing a migration
Using Dashboard
When you open a Chat application overview for the app that uses older version of permissions, you will see a popup suggesting you to perform an upgrade.
Click “Upgrade” and wait until the page refreshes. Now you should be able to access new “Roles and Permissions” page to set up the permission settings.
You can also navigate directly to the “Roles & Permissions” page under chat settings and click “Upgrade” on the prompt shown there.
This upgrade option translates old permission settings the new system automatically, but we encourage you to visit “Roles and Permissions” page to double check that the configuration is correct.
Using API
In order to migrate to permissions “v2” you have to perform exactly this API call to UpdateApp API endpoint:
$client->updateAppSettings([
'permission_version' => 'v2',
'migrate_permissions_to_v2' => true,
])
client.update_app_settings(permission_version="v2", migrate_permissions_to_v2=True)
App.update().permissionVersion(App.PermissionVersion.V2).migratePermissionsToV2(true).request();
var settings = new AppSettings
{
MigratePermissionsToV2 = true,
PermissionVersion = PermissionVersion.V2,
};
await client.UpdateAppSettings(settings);
client.update_app_settings(permission_version: 'v2', migrate_permissions_to_v2: true)
doMigrate := true
settings := &AppSettings{
MigratePermissionsToV2: &doMigrate,
PermissionVersion: "v2",
}
resp, err := client.UpdateAppSettings(ctx, settings)
permission_version
field controls which permission system version is active. You can switch back and forth without providing any extra fields, but in order to convert all your existing configuration, you should provide "migrate_permissions_to_v2": true
. When this flag is present, Chat API translates v1 configuration to v2 for you which ensures that your app functions properly without any interruptions. You can always switch back to v1, but configuration translation only works one way. You can also prepare permissions v2 configuration manually and switch to the new version without providing migrate_permissions_to_v2
flag
We recommend you to take a good look at the resulting grants configuration and make sure that all permissions there are correct. Even better if you can test these configurations in development before updating production
How to switch back
In case something goes wrong for you, you can switch back to legacy permission system:
await client.updateAppSettings({
permission_version: "v1"
})
$client->updateAppSettings([
'permission_version' => 'v1',
])
client.update_app_settings(permission_version="v1")
App.update().permissionVersion(App.PermissionVersion.V1).request();
var settings = new AppSettings
{
PermissionVersion = PermissionVersion.V1,
};
await client.UpdateAppSettings(settings);
client.update_app_settings(permission_version: 'v1')
settings := &AppSettings{
PermissionVersion: "v1",
}
resp, err := client.UpdateAppSettings(ctx, settings)
New Global Roles
For multi-tenant applications only
Once you migrate to v2 permissions there will be two new roles available. These roles allow users to be Admins or Moderators across all teams. Previously, all users had to belong to a team and could only access channels and messages belonging to the same teams. These new roles allow access to all teams data and are important for users of the Stream Dashboard.
To change the role of Admin Users to Global Admin, or to change the role of Moderators to Global Moderator, you can use UpdateUser API endpoint:
await client.partialUpdateUser({id: "james_bond", set: {role: "global_moderator"}})
$client->partialUpdateUsers([
'id' => 'james_bond',
'set' => [
'role' => 'global_moderator',
],
])
response = client.update_user_partial(
{"id": "james_bond", "set": {"role": "global_moderator"}}
)
var update =
UserPartialUpdateRequestObject.builder()
.id("james_bond")
.setValue("role", "global_moderator")
.build();
User.partialUpdate().user(update).request();
var result = await client.Users.UpdatePartial(new UserPartialRequest
{
ID = "james_bond",
Set = new Dictionary<string, string>
{
{ "role", "global_moderator" },
}
});
client.update_user_partial({
id: 'james_bond',
set: { role: 'global_moderator' }
})
update := PartialUserUpdate{
ID: "james_bond",
Set: map[string]interface{}{
"role": "global_moderator",
},
}
resp, err := c.PartialUpdateUsers(ctx, []PartialUserUpdate{update})