Query-based Sync permissions
Query-based Sync is not recommended. For applications using Realm Sync, we recommend Full Sync. Learn more about our plans for the future of Realm Sync here.

Overview

The Query-based sync permission system is based on role-based access control lists and as such, permissions are assigned to roles, not users directly. This means that a user's current privileges are the sum of all roles they belong to.
The permission system recognizes three levels of permissions: Realm, Class, and Object-level. The hierarchy works like this: If a user does not have higher-level Read access, they cannot see anything on the lower levels. For example, if a user lacks Read access at the Realm-level, they cannot see any data in the Realm, even if they have Read at the class or object-level. However, just because they have higher-level Read access does not mean they can see everything on the lower level -- just that they can see anything at all. In this way, the app developer can decide for themselves what granularity they want for permissions in their data model.
Query-based Sync Permissions were formerly referred to as Fine-grained Permissions
Overview of query-based sync permissions
When first starting, any user who can connect to a Realm file can make any change to the data. This is designed to allow you to get up and running quickly, syncing data, and iterating on your data models. Once you are ready to start implementing access control, an admin can define access control lists inside the Realm file, either on individual objects or whole classes.
Realm is an offline-first database, but permission checks are performed by the server. When a user makes a change to their local database, it will eventually be uploaded to the server, but if the server determines that the user tried to make changes that they were not allowed to make, the server will refuse to integrate it and instruct the client to revert the change. This all happens transparently from the perspective of the app.
A reversal of an illegal change looks like any other change coming from the server.
To minimize the risk of a user unintentionally making illegal changes while offline, the permission metadata is replicated to each client for offline access, and can be queried in the app for UI purposes. No permission checks are done automatically by the client -- the app has to manually query the permission metadata.

Roles

The query-based sync permission model is based on roles. Roles are granted permissions, not users, but users, in turn, are assigned roles. This way, a users privileges are the sum of all roles they are part of.
A user can be a member of as many roles as needed. The Realm Object Server automatically adds all users to the special role called everyone when they first connect.
A unique role is also automatically created for every user in the system when they first connect: __User:<syncIdentity>. The user is also automatically a member of this role.
In a new Realm file, the everyone role has all permissions enabled.
When you as a developer are ready to integrate permissions in your app, you would usually define a new administrator role which has yourself as a member, and then reduce the privileges of the everyone role. Note that an administrator role is different than an admin user on the Realm Object Server.
When assigning a role to a User, the user is added as a member of the Role object instead of the role being attached to the user. Since the Role object is just a normal Realm object, it can be found, queried and manipulated the same way as other objects:
Swift
Objective-C
Java
Javascript
.Net
1
// List all roles
2
let roles = realm.objects(PermissionRole.self)
3
4
// You can query roles in order to find a specific one
5
let role = realm.objects(PermissionRole.self).filter("name = %@", "my-role").first
6
7
// Making changes to a Role requires a write transaction
8
let user = getUserId()
9
try! realm.write {
10
role.users.append(user)
11
}
12
13
// So does creating a new role
14
try! realm.write {
15
let newRole = realm.create(PermissionRole.self, value: ["my-new-role"])
16
}
Copied!
1
// List all roles
2
RLMResults<RLMPermissionRole *> *roles = [RLMPermissionRole allObjectsInRealm:realm];
3
4
// You can query roles in order to find a specific one
5
RLMPermissionRole *role = [RLMPermissionRole objectsInRealm:realm where:@"name = %@", @"my-role"].firstObject;
6
7
// Making changes to a Role requires a write transaction
8
RLMPermissionUser *user = getUserId();
9
[realm transactionWithBlock:^{
10
[role.users addObject:user];
11
}];
12
13
// So does creating a new role
14
[realm transactionWithBlock:^{
15
[RLMPermissionRole createInRealm:realm withValue:@[@"my-new-role"]];
16
}];
Copied!
1
// List all roles
2
RealmResults<Role> roles = realm.getRoles();
3
4
// You can query roles in order to find a specific one
5
Role role = realm.getRoles().where()
6
.equalTo("name", "my-role")
7
.findFirst();
8
9
// Making changes to a Role requires a write transaction
10
String user = getUserId();
11
realm.executeTransaction((Realm r) -> {
12
role.addMember(user);
13
});
14
15
// So does creating a new role
16
realm.executeTransaction((Realm r) -> {
17
r.insert(new Role("my-new-role"));
18
});
Copied!
1
// List all roles
2
let roles = realm.objects(Realm.Permissions.Role);
3
4
// You can query roles in order to find a specific one
5
let role = realm
6
.objects(Realm.Permissions.Role)
7
.filtered(`name = 'my-role'`)[0];
8
9
// Making changes to a Role requires a write transaction
10
let user = getUser();
11
realm.write(() => {
12
role.members.push(user);
13
})
14
15
// So does creating a new role
16
realm.write(() => {
17
realm.create(Realm.Permissions.Role, { name: "my-new-role" });
18
});
Copied!
1
// List all roles
2
var roles = realm.All<PermissionRole>();
3
4
// You can query roles in order to find a specific one
5
var role = realm.All<PermissionRole>().FirstOrDefault(r => r.Name == "my-role");
6
7
// Making changes to a Role requires a write transaction
8
realm.Write(() =>
9
{
10
var user = PermissionUser.Get(realm, "some-user-id");
11
role.Users.Add(user);
12
});
13
14
// So does creating a new role
15
realm.Write(() =>
16
{
17
var newRole = PermissionRole.Get(realm, "my-new-role");
18
});
Copied!

Granting Roles Permissions

Once you have a Role, it can be granted permissions. This is done by creating a Permission object containing that role:
Swift
Objective-C
Java
Javascript
.Net
1
// Create Permission object that grants read and update privileges to a Role
2
try! realm.write {
3
let permission = realm.create(Permission.self, value: {
4
role: getRole(),
5
canRead: true,
6
canUpdate: true
7
})
8
}
Copied!
1
// Create Permission object that grants read and update privileges to a Role
2
[realm transactionWithBlock:^{
3
[RLMPermission createInRealm:realm withValue:@{
4
@"role": getRole(),
5
@"canRead": @YES,
6
@"canUpdate": @YES
7
}];
8
}];
Copied!
1
// Create Permission object that grants read and update privileges to a Role
2
Role role = getRole();
3
Permission permission = new Permission.Builder(role)
4
.canRead(true)
5
.canUpdate(true)
6
.build();
Copied!
1
// Create Permission object that grants read and update privileges to a Role
2
let permission = realm.create(Realm.Permissions.Permission, {
3
role: getRole(),
4
canRead: true,
5
canUpdate: true,
6
});
Copied!
1
// Create Permission object that grants read and update privileges to a Role
2
realm.Write(() =>
3
{
4
// The permission can be associated with a Realm, a class, or an object.
5
// Alternatively, you can pass in a collection of permissions to add the
6
// new one to.
7
var permission = Permission.Get("my-role", realm);
8
permission.CanRead = true;
9
permission.CanUpdate = true;
10
});
Copied!
By itself, the Permission object does nothing and the privileges described in the object are not enforced until the object has been added to an appropriate permission list at either the Realm-level, the Class-level or the Object-level. See the respective subsections for details on how to do this.
A single Permission object can be used in multiple places at the same time. This can be useful if you easily want to update privileges across multiple objects at the same time.
The following privileges can be set when creating or modifying the Permission object:
  • canCreate
  • canRead
  • canUpdate
  • canDelete
  • canSetPermissions
  • canQuery
  • canModifySchema
These privileges have different semantics depending on the level they are applied. See the sections below for the meaning of each privilege at the given level.

Realm-level permissions

Realm-level permissions apply globally to the Realm file and are modified through a special singleton Realm object that is accessed the following way:
Swift
Objective-C
Java
Javascript
.Net
1
// List all Realm-level permissions
2
let realmPermissions = realm.permissions
3
4
// Find Realm level permissions for a given role
5
let rolePermissions = realmPermissions.filter("role.name = %@", "my-role").first
Copied!
1
// List all Realm-level permissions
2
RLMRealmPermissions *permissions = [RLMRealmPermissions objectInRealm:realm];
3
4
// Find Realm level permissions for a given role
5
RLMPermission *rolePermissions = [permissions objectsWhere:@"role.name = %@", @"my-role"]
Copied!
1
// Get the wrapper object for all Realm-level permissions
2
RealmPermissions realmPermissions = realm.getPermissions()
3
4
// List all Realm-level permissions
5
RealmList<Permission> allPermissions = realmPermissions.getPermissions()
6
7
// Find permissions for a given role
8
Permission rolePermissions = realmPermissions.getPermissions()
9
.equalTo("role.name", "my-role")
10
.findFirst()
Copied!
1
// Get the global Realm-level permissions object
2
let realmPermissions = realm.permissions();
3
4
// Find permissions for a given role
5
let rolePermissions = realmPermissions.permissions
6
.filtered(`role.name = 'my-role'`)[0];
7
8
// List the Realm-level permissions for all roles
9
let allPermissions = realmPermissions.permissions;
Copied!
1
// List all Realm-level permissions
2
var realmPermissions = RealmPermission.Get(realm).Permissions;
3
4
// Find Realm level permissions for a given role
5
var rolePermissions = realmPermissions.FirstOrDefault(p => p.Role.Name == "my-role");
Copied!
Adding Realm-level permissions for a role is done by adding a new Permission object to the list of Realm-level permissions. This requires a write transaction:
Swift
Objective-C
Java
Javascript
.Net
1
// Adding new permissions must be done within a write transaction
2
try! realm.write {
3
// Grant read-only access at the Realm-level, which means
4
// that users with this role can read all objects in the Realm
5
// unless restricted by Class or Object level permissions.
6
let permissions = realm.permissions.findOrCreate(forRoleNamed: "my-role")
7
permissions.canRead = true
8
permissions.canQuery = true
9
}
Copied!
1
// Permissions must be modified inside a write transaction
2
[realm transactionWithBlock:^{
3
// Grant read-only access at the Realm-level, which means
4
// that users with this role can read all objects in the Realm
5
// unless restricted by Class or Object level permissions.
6
RLMPermission *permissions = [RLMPermission permissionForRoleNamed:@"my-role" onRealm:realm];
7
permissions.canRead = true;
8
permissions.canQuery = true;
9
}];
Copied!
1
// Adding new permissions must be done within a write transaction
2
realm.executeTransaction((Realm r) -> {
3
RealmPermissions realmPermissions = realm.getPermissions()
4
5
// Grant read-only access at the Realm-level, which means
6
// that users with this role can read all objects in the Realm
7
// unless restricted by Class or Object level permissions.
8
Permission permissions = realmPermissions.findOrCreate("my-role")
9
permissions.setCanRead(true)
10
permissions.setCanQuery(true)
11
});
Copied!
1
// Adding new permissions must be done within a write transaction
2
realm.write(() => {
3
let realmPermissions = realm.permissions().permissions;
4
5
// Grant read-only access at the Realm-level, which means
6
// that users with this role can read all objects in the Realm
7
// unless restricted by Class or Object level permissions.
8
let role = realm.objects(Realm.Permissions.Role)
9
.filtered(`name = 'my-role'`)[0];
10
let permission = realm.create(Realm.Permissions.Permission, {
11
role: role,
12
canRead: true,
13
canQuery: true,
14
});
15
16
// Add it to the list of permissions for it to take affect.
17
realmPermissions.push(permission);
18
});
Copied!
1
// Adding new permissions must be done within a write transaction
2
realm.Write(() =>
3
{
4
// Grant read-only access at the Realm-level, which means
5
// that users with this role can read all objects in the Realm
6
// unless restricted by Class or Object level permissions.
7
var permission = Permission.Get("my-role", realm);
8
permission.CanRead = true;
9
permission.CanQuery = true;
10
});
Copied!
Modifying the Realm-level permissions for an existing role is done by finding the permission object for that role and modifying it. This requires a write transaction:
Swift
Objective-C
Java
Javascript
.Net
1
// Modifying permissions must be done within a write transaction
2
try! realm.write {
3
// Find permissions for the specific role
4
let permission = realm.permissions.findOrCreate(forRoleNamed: "my-role")
5
6
// Prevent `my-role` users from modifying any objects in the Realm.
7
permission.canUpdate = false
8
permission.canDelete = false
9
}
Copied!
1
// Permissions must be modified inside a write transaction
2
[realm transactionWithBlock:^{
3
// Find permissions for the specific role
4
RLMPermission *permissions = [RLMPermission permissionForRoleNamed:@"my-role" onRealm:realm];
5
6
// Prevent `my-role` users from modifying any objects in the Realm.
7
permissions.canRead = false;
8
permissions.canQuery = false;
9
}];
Copied!
1
// Modifying permissions must be done within a write transaction
2
realm.executeTransaction((Realm r) -> {
3
RealmPermissions realmPermissions = realm.getPermissions();
4
5
// Find permissions for the specific role
6
Permission permission = realmPermissions.findOrCreate("my-role");
7
8
// Prevent `my-role` users from modifying any objects in the Realm.
9
permission.setCanUpdate(false);
10
permission.setCanDelete(false);
11
});
Copied!
1
// Modifying permissions must be done within a write transaction
2
realm.write(() => {
3
let realmPermissions = realm.permissions().permissions;
4
5
// Find permissions for the specfic role
6
let permission = realmPermissions.filtered('role.name', 'my-role')[0];
7
8
// Prevent `my-role` users from modifying any objects in the Realm.
9
permission.canUpdate = false;
10
permission.canDelete = false;
11
});
Copied!
1
// Modifying permissions must be done within a write transaction
2
realm.Write(() =>
3
{
4
// Find permissions for the specific role
5
var permission = Permission.Get("my-role", realm);
6
permission.CanUpdate = false;
7
permission.CanDelete = false;
8
});
Copied!
Normal users can only grant other people access up to the level they themselves have, and only if they have the SetPermissions privilege. Realm Object Server admin users can see and edit everything.
The following table describes the effect of enabling or disabling privileges at the Realm level. If a privilege is marked with N/A it means that the privilege has no meaning at this level beyond being required to enable setting it at Class or Object level.
Type
ENABLED
DISABLED
canCreate
N/A
N/A
canRead
Role can see the Realm file itself, i.e. being able to meaningfully connect to it. Being able to see individual classes are covered by Class-level permissions.
Role cannot see anything in the Realm file. An user that is offline will still create the file and schema locally on the device, but as soon as the device connects to the server, it will revert all changes (leaving an empty Realm). This will most likely crash the app.
canUpdate
Role can make changes to objects in the Realm file. This does not include schema changes or changes to permissions which are covered by canModifySchema andcanSetPermissions.
Role cannot change anything in the Realm file. It is read-only. Note that the user can write changes to the Realm file while offline, but any change will be reverted by the server once the device is online again.
canDelete
N/A
N/A
canQuery
N/A
N/A
canSetPermissions
Role can set Realm-level permissions. A user with theSetPermissions privilege can never give other users higher privileges than they themselves have.
Role cannot set or change Realm-level permissions.
canModifySchema
Role can add classes to the schema, but not properties which are covered by Class-level permissions.
Role cannot modify the schema in the entire Realm.

Class-level permissions

Class-level permissions are permissions related to all objects of a given type.
They can be used reduce the scope of a Realm-level privilege, but cannot be used to broaden a privilege granted at the Realm-level. E.g. if canRead is set at the Realm-level, it is possible to set canRead to false at the Class-level, which will prevent the Role from seeing just this single class. However, if canRead was not set set the Realm-level, the value of canRead at the Class-level will be ignored and the class will not be readable.
Just like Realm-level permissions, Class-level permissions are exposed as Realm objects that can be accessed the following way:
Swift
Objective-C
Java
Javascript
.Net
1
// List the Class-level permissions for the given model class
2
let classPermissions = realm.permissions(forType: Person.self)
3
4
// Find Class-level permissions for a given role
5
let rolePermissions = classPermissions.filter("role.name = %@", "my-role").first
Copied!
1
// List the Class-level permissions for the given model class
2
RLMClassPermission *classPermissions =
3
[RLMClassPermission objectInRealm:realm forClass:Person.class];
4
5
// Find Class-level permissions for a given role
6
RLMPermission *rolePermissions = [[classPermissions.permissions
7
objectsWhere:@"role.name = %@", @"my-role"]
8
firstObject];
Copied!
1
// Get the Class-level permissions object for the Person class
2
ClassPermissions classPermissions = realm.getPermissions(Person.class);
3
4
// List the Class-level permissions for all roles
5
RealmList<Permission> permissions = classPermissions.getPermissions();
6
7
// Find Class-level permissions for a given role
8
Permission rolePermissions = classPermissions.getPermissions().where()
9
.equalTo("role.name", "my-role")
10
.findFirst();
Copied!
1
// Get the Class-level permissions object for the Person class
2
let classPermissions = realm.permissions('Person');
3
4
// List the Class-level permissions for all roles
5
let permissions = classPermissions.permissions;
6
7
// Find Class-level permissions for a given role
8
let rolePermissions = classPermissions.permissions
9
.filtered(`role.name = 'my-role'`)[0];
Copied!
1
// List the Class-level permissions for the given model class
2
var classPermissions = ClassPermission.Get<Person>(realm).Permissions;
3
4
// Find Class-level permissions for a given role
5
var rolePermission = classPermissions.FirstOrDefault(p => p.Role.Name == "my-role");
Copied!
Adding Class-level permissions for a role is done by adding a new Permission object to the list of permissions. This requires a write transaction:
Swift
Objective-C
Java
Javascript
.Net
1
// Adding new permissions must be done within a write transaction
2
try! realm.write {
3
// Remove read-access for the Person class for users with the `my-role` role.
4
let permission = realm
5
.permissions(forType: Person.self)
6
.findOrCreate(forRoleNamed: "my-role")
7
permission.canRead = false
8
});
Copied!
1
// Adding new permissions must be done within a write transaction
2
[realm transactionWithBlock:^{
3
// Remove read-access for the Person class for users with the `my-role` role.
4
RLMPermission *permission = [RLMPermission permissionForRoleNamed:@"my-role"
5
onClass:Person.class
6
realm:realm];
7
permission.canRead = false;
8
});
Copied!
1
// Adding new permissions must be done within a write transaction
2
realm.executeTransaction((Realm r) -> {
3
ClassPermissions realmPermissions = realm.getPermissions(Person.class);
4
5
// Remove read-access for the Person class for users with the `my-role` role.
6
Role role = realm.where(Role.class).equalTo("name", "my-role").findFirst();
7
Permission p = new Permission.Builder(role)
8
.canRead(false)
9
.build();
10
11
// Add it to the list of permissions for it to take affect.
12
classPermissions.getPermissions().add(permission);
13
});
Copied!
1
// Adding new permissions must be done within a write transaction
2
realm.write(() => {
3
let realmPermissions = realm.permissions('Person').permissions;
4
5
// Remove read-access for the Person class for users with `my-role` role.
6
let role = realm.objects(Realm.Permissions.Role)
7
.filtered(`name = 'my-role'`)[0];
8
9
let permission = realm.create(Realm.Permissions.Permission, {
10
role: role,
11
canRead: false,
12
});
13
14
// Add it to the list of permissions for it to take affect.
15
classPermissions.push(permission);
16
});
Copied!
1
// Adding new permissions must be done within a write transaction
2
realm.Write(() =>
3
{
4
var permission = Permission.Get<Person>("my-role", realm);
5
6
// Alternatively, there's a string-based API if, for some reason,
7
// you can't use the generic one.
8
// var permission = Permission.Get("my-role", "Person", realm);
9
10
permission.CanRead = false;
11
});
Copied!
Modifying the Class-level permissions for an existing role is done by finding the permission object for that role and modify it. This requires a write transaction:
Swift
Objective-C
Java
Javascript
.Net
1
// Modifying permissions must be done within a write transaction
2
try! realm.write {
3
// Find permissions for the role and change it
4
let permission = realm
5
.permissions(forType: Person.self)
6
.findOrCreate(forRoleNamed: "my-role")
7
8
// Prevent `my-role` users from modifying any Person objects.
9
permission.canUpdate = false
10
permission.canDelete = false
11
});
Copied!
1
// Modifying permissions must be done within a write transaction
2
[realm transactionWithBlock:^{
3
RLMPermission *permission = [RLMPermission permissionForRoleNamed:@"my-role"
4
onClass:Person.class
5
realm:realm];
6
7
// Prevent `my-role` users from modifying any Person objects.
8
permission.canUpdate = false;
9
permission.canDelete = false;
10
});
Copied!
1
// Modifying permissions must be done within a write transaction
2
realm.executeTransaction((Realm r) -> {
3
ClassPermissions classPermissions = realm.getPermissions(Person.class);
4
5
// Find permissions for the role and change it
6
Permission permission = classPermissions.getPermissions().where()
7
.equalTo("role.name", "my-role")
8
.findFirst();
9
10
// Prevent `my-role` users from modifying any Person objects.
11
permission.setCanUpdate(false);
12
permission.setCanDelete(false);
13
});
Copied!
1
// Modifying permissions must be done within a write transaction
2
realm.write(() => {
3
let classPermissions = realm.permissions('Person').permissions;
4
5
// Find permissions for a specfic role
6
let permission = classPermissions.filtered(`role.name = 'my-role'`)[0];
7
8
// Prevent `my-role` users from modifying any objects in the Realm.
9
permission.canUpdate = false;
10
permission.canDelete = false;
11
});
Copied!
1
// Modifying permissions must be done within a write transaction
2
realm.Write(() =>
3
{
4
var permission = Permission.Get<Person>("my-role", realm);
5
// Prevent `my-role` users from modifying any Person objects.
6
permission.CanUpdate = false;
7
permission.CanDelete = false;
8
});
Copied!
Normal users can only grant other people access up to the level they themselves have, and only if they have the SetPermissions privilege. Admin users can see and edit everything.
The following table describes the effect of enabling or disabling a given privilege at the Class level. If a privilege is marked with N/A it means that the privilege has no meaning at this level beyond being required to enable setting it at the Object level.
Type
ENABLED
DISABLED
canCreate
Role can create objects of this type.
If a user has the canCreate privilege, but not canUpdate,they are still able to modify newly-created objects inside the same transaction that object was created in.
Role cannot create objects of this type.
canRead
Role can see objects of this type.
Role cannot see any objects of this type. It is still allowed to query them, but the query result will be empty
canUpdate
Role can change properties in objects of this type.
Role cannot make any change to properties in objects of this type.
canDelete
N/A
N/A
canQuery
Role is allowed to create a server side Subscription for this type.
Role is not allowed to create a server side Subscription for this type. Note: Local queries will always work.
canSetPermissions
Role can set Class-level permissions for the class.
Role cannot set class-level permissions for the class.
canModifySchema
Role can add properties to this class. Deleting and renaming fields is currently not supported by the Realm Object Server.
Role cannot modify the schema for this class.

Object-level permissions

Object-level permissions are permissions related to a single Realm object.
They can be used to reduce the scope of Class-level privileges, but cannot be used to broaden a privilege granted at the Class-level. E.g. if canRead is enabled at the Class-level, it is possible to disable canRead at the Object-level which will prevent the Role from seeing just this single object. However, if canRead was disabled at the Class-level, no matter the value of canRead at the Object-level the object will not be readable.
In order to add permissions to your objects, you must add a special Access Control List (ACL) property. If your objects do not have the ACL property, the objects will be fully accessible by anyone (provided that they are discoverable -- see the canQuery/canRead permission at the Class level).
The ACL property is added the following way:
Swift
Objective-C
Java
Javascript
.Net
1
// The ACL property is a `List<Permission>` field with a user-defined name
2
class Person: Object {
3
@objc dynamic var name = ""
4
let permissions = List<Permission>()
5
}
Copied!
1
// The ACL property is a `RLMArray<RLMPermission *>` field
2
// with a user-defined name
3
@interface Person : RLMObject
4
@property NSString *name;
5
@property RLMArray<RLMPermission *><RLMPermission> *permissions;
6
@end
Copied!
1
// The ACL property is a `RealmList<Permission>` field
2
// with a user-defined name
3
public class Person extends RealmObject {
4
public String name;
5
public RealmList<Permission> permissions = new RealmList<>();
6
}
Copied!
1
// The ACL property is a list-of-permission property
2
// with a user-defined name
3
const PersonSchema = {
4
name: 'Person',
5
properties: {
6
name: 'string',
7
permissions: '__Permission[]'
8
}
9
};
Copied!
1
// The ACL property is an `IList<Permission>` property with a user-defined name
2
public class Person : RealmObject
3
{
4
// Other properties ...
5
6
public IList<Permission> Permissions { get; }
7
}
Copied!
If there is an ACL property, but no permissions have been added for any role, then nobody except Realm Object Server admin users will have access to the object. This includes the user creating the object.
Adding Object-level permissions for a role is done adding a new Permission object to the list of permissions. This requires a write transaction:
Swift
Objective-C
Java
Javascript
.Net
1
// Adding new permissions must be done within a write transaction
2
try! realm.write {
3
// Grant users with the `shared-objects` role access to read and modify
4
// this object
5
let person = getPerson()
6
let permissions = person.permissions.findOrCreate(forRoleNamed: "shared-objects")
7
permissions.canRead = true
8
permissions.canUpdate = true
9
permissions.canDelete = true
10
}
Copied!
1
// Adding new permissions must be done within a write transaction
2
[realm transactionWithBlock:^{
3
// Grant users with the `shared-objects` role access to read and modify
4
// this object
5
Person *person = getPerson();
6
RLMPermission *permissions = [RLMPermission
7
permissionForRoleNamed:@"shared-objects"
8
inArray:person.permissions];
9
permissions.canRead = true;
10
permissions.canUpdate = true;
11
permissions.canDelete = true;
12
}];
Copied!
1
// Adding new permissions must be done within a write transaction
2
realm.executeTransaction((Realm r) -> {
3
Person p = realm.where(Person.class).equalto("id", getId()).findFirst()
4
5
// Grant users with the `shared-objects` role access to read and modify
6
// this object
7
Role role = realm.where(Role.class)
8
.equalTo("name", "shared-objects")
9
.findFirst();
10
Permission p = new Permission.Builder(role)
11
.canRead(true)
12
.canUpdate(true)
13
.canDelete(true)
14
.build();
15
16
// Add it to the list of permissions associated with the object
17
// for it to take affect.
18
p.permissions.add(permission);
19
});
Copied!
1
// Adding new permissions must be done within a write transaction
2
realm.write(() => {
3
let person = realm.objects('Person').filtered(`id = "my-id"`)[0];
4
5
// Grant users with the `shared-objects` role access to read and modify
6
// this object
7
let role = realm.objects(Realm.Permissions.Role)
8
.filtered(`id = "shared-objects"`)[0];
9
let permission = realm.create(Realm.Permissions.Permission, {
10
role: role,
11
canRead: true,
12
canUpdate: true,
13
canDelete: true,
14
});
15
16
// Add it to the list of permissions for it to take affect.
17
person.permissions.push(permission);
18
});
Copied!
1
var person = GetSomePerson();
2
// Adding new permissions must be done within a write transaction
3
realm.Write(() =>
4
{
5
// Grant users with the `shared-objects` role access to read and modify
6
// this object. Using the Permission.Get API that accepts a RealmObject
7
// will use reflection to find the `IList<Permission>` property.
8
var permission = Permission.Get("shared-objects", person);
9
10
// Alternatively, you can pass in the permission collection directly:
11
// var permission = Permission.Get("shared-objects", person.Permissions);
12
13
permission.CanRead = true;
14
permission.CanUpdate = true;
15
permission.CanDelete = true;
16
});
Copied!
Modifying the Object-level permissions for an existing role is done by finding the permission object for that role and modifying it. This requires a write transaction:
Swift
Objective-C
Java
Javascript
.Net
1
// Modifying permissions must be done within a write transaction
2
try! realm.write {
3
let person = getPerson()
4
5
// Prevent `shared-objects` users from modifying this object.
6
let permissions = person.permissions.findOrCreate(forRoleNamed: "shared-objects")
7
permissions.canUpdate = false
8
permissions.canDelete = false
9
}
Copied!
1
// Modifying permissions must be done within a write transaction
2
[realm transactionWithBlock:^{
3
Person *person = getPerson();
4
// Prevent `shared-objects` users from modifying this object.
5
RLMPermission *permissions = [RLMPermission
6
permissionForRoleNamed:@"shared-objects"
7
inArray:person.permissions];
8
permissions.canUpdate = false
9
permissions.canDelete = false
10
}];
Copied!
1
// Modifying permissions must be done within a write transaction
2
realm.executeTransaction((Realm r) -> {
3
Person p = realm.where(Person.class).equalTo("id", getId()).findFirst();
4
5
// Find permissions for a specific role and change them
6
Permission permission = p.permissions.where()
7
.equalTo("role.name", "shared-objects")
8
.findFirst();
9
10
// Prevent `shared-objects` users from modifying this object.
11
permission.setCanUpdate(false);
12
permission.setCanDelete(false);
13
});
Copied!
1
// Modifying permissions must be done within a write transaction
2
realm.write(() => {
3
let person = realm.objects('Person')
4
.filtered(`id = "${getId()}"`)[0];
5
6
// Find permissions for a specific role and change them
7
let permission = person.permissions('role.name', 'shared-objects')[0];
8
9
// Prevent `shared-objects` users from modifying this object.
10
permission.canUpdate = false;
11
permission.canDelete = false;
12
});
Copied!
1
var person = GetSomePerson();
2
// Modifying permissions must be done within a write transaction
3
realm.Write(() =>
4
{
5
// Prevent `shared-objects` users from modifying this object.
6
var permission = Permission.Get("shared-objects", person);
7
permission.CanUpdate = false;
8
permission.CanDelete = false;
9
});
Copied!
Any object that is reachable through links or collections from an object to which a user has Read access will also be readable by that user, even if they explicitly do not have Read access to the reachable object. This is due to a current limitation in the way object graphs are represented in Realm.
The following table describes the effect of enabling or disabling a given privilege at the Object level:
Type
ENABLED
DISABLED
canCreate
N/A
N/A
canRead
Role can see and read this object. This include any referenced objects.
Role cannot read or see this object.
canUpdate
Role can update properties on this object. The ACL property is a special case handled by canSetPermissions.
Role is not allowed to change the value of any properties on the object.
canDelete
Role can delete the object.
Role is not allowed to delete the object.
canQuery
N/A
N/A
canSetPermissions
Role can modify Permission objects referenced by the custom ACL property on the object.
Role is not allowed to modify the custom ACL property on the object.
canModifySchema
N/A
N/A

User Privileges

Because a User can be part of multiple roles with many different permissions, it is often useful to be able to determine exactly what the current user can do with an object (or class, or the Realm file).
This can be achieved in the following way:
Swift
Objective-C
Java
Javascript
.Net
1
// Realm privileges
2
let privileges = realm.getPrivileges()
3
4
// Class privileges for `Person`
5
let privileges = realm.getPrivileges(Person.self)
6
7
// Object privileges
8
let person = getPerson()
9
let privileges = realm.getPrivileges(person)
Copied!
1
// Realm privileges
2
struct RLMRealmPrivileges privileges = [realm privilegesForRealm];
3
4
// Class privileges for `Person`
5
struct RLMClassPrivileges privileges = [realm privilegesForClass:Person.class];
6
7
// Object privileges
8
Person *person = getPerson();
9
struct RLMObjectPrivileges privileges = [realm privilegesForObject:person];
Copied!
1
// Realm privileges
2
RealmPrivileges privileges = realm.getPrivileges();
3
4
// Class privileges for `Person`
5
ClassPrivileges privileges = realm.getPrivileges(Person.class);
6
7
// Object privileges
8
Person person = getObject();
9
ObjectPrivileges privileges = realm.getPrivileges(person);
Copied!
1
// Realm privileges
2
let privileges = realm.privileges();
3
4
// Class privileges for `Person`
5
let classPrivileges = realm.privileges('Person');
6
7
// Object privileges
8
let person = getPerson();
9
let objectPrivileges = realm.getPrivileges(person);
Copied!
1
// Realm privileges
2
var privileges = realm.GetPrivileges();
3
4