Access Control

3
Last updated 8 days ago

As you progress in your app development, eventually you will want to consider data security. Realm Platform offers a variety of mechanisms to securely control access to your synchronized data.

Full-Sync Permissions

Access control of full Realm synchronizations is based on the specific Realm path, such as /globalRealm or /~/myRealm. To limit data access to specific users or groups, data must be organized in separate Realms, such as a global read-only Realm (i.e. /globalRealm) for data all users need to access, and user-specific Realms (i.e. /~/myRealm) for data that should only be accessible to individual users.

These permissions cannot be applied to query-based synchronizations. For more details see the dedicated guide:

Query-based Sync Permissions

Query-based synchronization introduces its own permissions model which works on more levels than its full-sync counterpart.

  • Realm-level permissions - permissions that apply to the entire Realm file (this is similar to path-level permissions, but has a different API that aligns with class/object-level permissions)

  • Class-level permissions - permissions that apply only to a specific object class within a Realm file

  • Object-level permissions - permissions that apply only to a specific object within a Realm file

It is worth noting that this added complexity also comes with reduced performance.

Comparison

To help clarify the differences between the various permissions, this visualization shows the difference between full-sync (formerly known as path-level) permissions and query-based (formerly known as fine-grained) permissions, and how the levels relate to each other .

Comparison of full-sync and query-based sync permissions

Full-sync permissions are designed to control access to multiple Realms based on the server URL path. When you open a Realm and supply the URL, the client SDK communicates with the server to obtain an access token. This token is granted if the user has read or read/write permissions to the requested Realm. If the user does not have access, then no token is granted, an error is passed to the client, and no sync session is established.

Query-based permissions work differently than full-sync permissions. When you open a query-based Realm, such as the default synced Realm, the client will initially contain no data. Once the client subscribes to a query, the access control system evaluates what objects to return through an ordered series of layers. Let's walk through an example of a client simply trying to Read data.

  1. Realm-level permissions are evaluated first to check if the user has Read access. If no, then the client Realm will be empty. If yes, then the system continues to the next layer.

  2. Class-level permissions are evaluated second to check if the user has Read access to the class used in the query. If no, then the client Realm will remain empty since no objects match the query. If yes, then the system continues to the next layer.

  3. Object-level permissions are evaluated last to check which specific objects the user has Read access to that match the query. If the user has access to all or some objects, those objects will be synced with the client Realm.

By default, when a Realm or class is created, all users are granted full access. Whereas when objects are created, they do not contain an ACL, because by default, objects lacking an ACL are accessible by everyone. Following the example above, by default, this means that clients subscribing to a query will pass through the hierarchy at the Realm and class-level since they have Read access and then all objects would be used to evaluate the query since no objects will contain an ACL initially.

Best Practices

Where to Apply Permissions

Knowing where to apply the permissions code is dependent on the use case of your application. For instance, if data is created by mobile users and then must be shared to other users then the permissions code should be kept on the sync-client. A common use case would be for a field-service app where the worker notices a job that needs to get done, creates a ticket, assigns the ticket to a group of users using object level permissions and assignsthe canRead permission to the role that contains the group.

If the data is mission critical with extensive security requirements and is often pushed down to mobile clients then it is recommended to keep the permissions in a server-side admin-only app. For example, a medical app might have different levels of access for their treatment data such as doctor, nurse, and patient. Each role would only see a subset of the treatment data contained in the treatment realm.

Not what you were looking for? Leave Feedback