How ReBAC helps solve data filtering

Apr 12th, 2024

Omri Gazitt avatar

Omri Gazitt

ReBAC  |  

Topaz  |  

Authorization

authorization lock

The move to fine-grained authorization

Authorization is the process of determining whether a subject (typically a user) has a permission on an object in a system. In coarse-grained systems, the permission often relates to an entire tenant. For example, a multi-tenant RBAC model defines a viewer role with permissions to view all the objects in that tenant.

In the past few years we’ve seen a move to finer-grained authorization models. Whether this shift is brought about by security concerns (applying the principle of least privilege), or customer demands (the ability to delegate permissions on fine-grained objects), the “object” in the authorization equation is now becoming a “document”, “resource”, or “item” inside of the tenant.

Data filtering

Once an application is trying to authorize at the item level, there are two obvious questions it needs to answer when rendering lists of items:

  • What items does a user have access to?
  • What users have access to an item?

Let’s take Google Drive as an example. A user should only see the set of documents that they own, or that are shared with them.  And an owner of a document may want to see what other users they’ve granted access to view, edit, or share that document.

These scenarios aren’t strictly speaking “authorization” scenarios, but a “close cousin”. In the past, authorization systems focused strictly on, well, authorization… but we’re now seeing a concerted effort to address these use-cases as well.

Authorization as a graph traversal

Google Drive employs a relationship-based access control (ReBAC) model. When authorization systems store or access information as a graph of objects connected by relationships, authorization becomes a graph traversal.

Let’s dive into a hypothetical Google Drive that Beth Smith set up for her family. The drive has a Root folder, which contains a Grocery list, the Family secrets document, Morty’s home folder, and Rick’s home folder.

root folder

In this example, all the documents in every folder can be accessed by Beth, because she’s the owner of the Root folder. This mirrors the semantics of Google Drive, where permissions are either directly assigned on a document, or inherited from permissions on the parent folder. This process can be evaluated transitively; this is why the relationship-based access control model defined by Google Drive is essentially a graph traversal.

Let’s look at the rest of the drive to fully flesh out the scenario.

Beth has made every user (*) a viewer of the Grocery list. This means that when we assess whether a user (such as Rick) has the can_read permission on the Grocery list, we can short-circuit the evaluation because every user is a viewer of that document.

grocery list

Next we have Morty’s home folder. It is owned by Morty, and contains Morty’s private journal (only accessible by Morty and… his mom 🤦), as well as Morty’s shared folder.

morty home folder

Morty’s shared folder only contains one document - Morty’s shared notes. But Morty has assigned the members of the editor-group the editor role on his shared folder, and members of the viewer-group the viewer role on that folder. This shows how specific permissions can be assigned to members of a group, which can be transitively (and recursively) computed.

morty shared folder

The editor-group includes Morty and Summer, and also contains members of the admin-group.

Members of the viewer-group include the editor-group, so that editors are viewers and admins are editors (and transitively, also viewers).

editors

Last but not least, Rick’s home folder contains his inventions, which he keeps private (except from the prying eyes of his daughter, Beth).

rick home folder

Determining whether Summer has the editor role on Morty’s shared notes simply means finding a set of graph edges that carry the correct permissions between Morty’s shared notes and Summer:

  • The parent of Morty’s shared notes is Morty’s shared folder
  • The members of the editor-group are editors of Morty’s shared folder
  • Summer is a member of the editor-group

Therefore, Summer can edit Morty’s shared notes.

Filtering is a graph traversal too!

Let’s say we want to find out which users have access to Morty’s shared notes. Notice that the process is almost identical, but instead of finding edges that connect that document to Summer specifically, we try to find edges that connect this document to ANY user.

This process may traverse more of the graph than the previous evaluation, which can terminate with a single subject. But an intelligent search algorithm will prune the paths and navigate the smallest possible subset.

In the Aserto Console, you can easily construct a query to return all the users that have the can_write permission on Morty’s shared notes:

find users

Copying the curl and executing it:

curl 'https://directory.prod.aserto.com/api/v3/directory/graph/doc/can_write/user?object_id=morty.shared.notes&subject_id=' \
  -H 'aserto-tenant-id: <tenant-id>' \
  -H 'authorization: basic <api-key>' \
  -H 'content-type: application/json' 
{
  "results": [
    {
      "object_type": "user",
      "object_id": "morty@the-citadel.com"
    },
    {
      "object_type": "user",
      "object_id": "beth@the-smiths.com"
    },
    {
      "object_type": "user",
      "object_id": "summer@the-smiths.com"
    },
    {
      "object_type": "user",
      "object_id": "rick@the-citadel.com"
    }
  ],
  "explanation": null,
  "trace": []
}

As we can see,

  • Morty is granted access because he’s the owner of Morty’s shared folder
  • Beth is granted access because she’s the owner of the Root folder
  • Summer is granted access because she’s a member of the editor-group
  • Rick is granted access because he’s a member of the admin-group, and the admin-group is a member of the editor-group

Filtering in the other direction

As we mentioned earlier, it’s also valuable to find out what a user has access to. To do this, we essentially have to invert the graph and walk it from the subject out to objects of a certain type, following edges that carry the permission we’re looking for.

In the Aserto Console, you can construct this query, to retrieve the objects of type doc for which Morty has the can_read permission:

find docs

Copying and executing the curl:

curl 'https://directory.prod.aserto.com/api/v3/directory/graph/doc/can_read/user?object_id=&subject_id=morty%40the-citadel.com' \
  -H 'aserto-tenant-id: <tenant-id>' \
  -H 'authorization: basic <api-key>' \
  -H 'content-type: application/json' 
{
  "results": [
    {
      "object_type": "doc",
      "object_id": "groceries"
    },
    {
      "object_type": "doc",
      "object_id": "morty.shared.notes"
    },
    {
      "object_type": "doc",
      "object_id": "morty.journal"
    }
  ],
  "explanation": null,
  "trace": []
}

As we can see, Morty has the can_read permission on:

  • The Groceries doc, since everyone does
  • The Morty shared notes doc, since it is in Morty’s shared folder, which in turn is in Morty’s home folder, and Morty is the owner of that folder
  • Morty’s journal, since it is is also in Morty’s home folder

How we do this graph inversion is a bit beyond the scope of this post (and involves some really cool tricks, which we may go over in a future post!)

Conclusion

When you model your authorization domain using relationship-based access control (ReBAC), you are essentially transforming authorization into a graph traversal problem.

You also get a very cool bonus - the ability to use your authorization system to determine which users have access to an item, or which items the logged-in user has access to.

Check it out in the Aserto Console, and if you don’t have an account, create a free one today! You can follow along this post by instantiating the Google Drive template and executing the Check, Find users, and Find objects requests in the Directory Evaluator.

Happy hacking!

Omri Gazitt avatar

Omri Gazitt

CEO, Aserto