Announcing Topaz 0.31: our spiciest edition yet!

Feb 29th, 2024

Omri Gazitt avatar

Omri Gazitt

Topaz  |  

Developers

Topaz open-source authorizer

In this latest version of Topaz, we’ve expanded the ReBAC / Zanzibar-inspired modeling capabilities, and now have support for the full complement of operators: union, intersection, exclusion, and relation navigation (arrow operator).

We’ve also added a set of authorization templates to show off how to use the new modeling capabilities to implement a few well-known domains - Google Drive, Slack, and GitHub. These templates can be a great starting point for your own authorization model.

Finally, the Aserto hosted platform, including the directory, console, and authorizer, now showcase these new Topaz capabilities. The Aserto Console has full support for the new templates, including Quickstarts for each.

Read on for more!

ReBAC modeling capabilities

Topaz 0.30, delivered in November 2023, adopted a new manifest language version, which overhauled how we express a domain model, enabling important new scenarios. With the new manifest language, we can specify the target types of a relation, and also how permissions are granted through relations.

Subject relations

With Topaz 0.31, we have added support for subject relations. This makes it possible to express relations not only to individual subjects, but also to sets. For example, in the following manifest, a group can have individual users as members, and can also be assigned the set of members of a specific group instance.


types:
  group:
    relations:
      member: user | group#member

In Topaz 0.30, the “member” relation of a group could have a “group” target type, and the implementation walked this relationship recursively to implement nested groups. In Topaz 0.31, this recursive behavior isn’t limited to groups, and can be specified explicitly by using a subject#relation as a target type.

In addition, with Topaz 0.30, a relation was fully specified as a 5-tuple: object type, object ID, relation, subject type, and subject ID. With Topaz 0.31, relations can now optionally specify a sixth field in the tuple - the subject relation, to distinguish the relation on the subject instance.

For example, to specify that the “viewer” group includes the members of the “editor” group, you can load the following relation into the Topaz directory:

{
  "object_type": "group",
  "object_id": "viewer",
  "relation": "member",
  "subject_type": "group",
  "subject_id": "editor",
  "subject_relation": "member"
}

Relations between types

Prior to Topaz 0.31, parent/child relationships were special-cased by using a relation explicitly called “parent”, which had transitive behavior. In Topaz 0.31, parent/child relationships can be explicitly defined, and aren’t transitive by default. For example, to model nested folders and documents, we can use the following manifest:

folder:
  relations:
    parent: folder
doc:
  relations:
    parent: folder

To define a permission that walks a folder hierarchy transitively, we would add it explicitly:

folder:
  relations:
    parent: folder
  permissions:
    is_parent: parent | parent->is_parent

Wildcard relations

Topaz 0.31 adds the ability to specify that the target of a relation can be ALL instances of a type. For example, the following manifest specifies that the “viewer” relation is assignable from a document to any number of specific user instances, as well as an instance that corresponds to ANY instance of type “user”:

document:
  relations:
    viewer: user | user:*

The most obvious use-case is for objects that can be “public” (i.e. any valid user can be assigned a permission to that object, without having to add every user to a group).

To create a wildcard relation, use an asterisk (‘*’) as the subject ID. For example:

 {
      "object_type": "document",
      "object_id": "doc1",
      "relation": "viewer",
      "subject_type": "user",
      "subject_id": "*"
 }

This adds a relation that gives all users the viewer relation to “doc1”.

Granting permissions

In Topaz 0.30, permissions could be granted through membership in ANY of a set of relations via the union (|) operator. For example, to grant the can_read permission to anyone who is either a viewer or has the can_write permission, the following permission definition can be used:

document:
  relations:
    viewer: user
    editor: user
  permissions:
    can_write: editor
    can_read: can_write | viewer

Topaz 0.31 adds a new set of operators, to enable far richer scenarios for granting permissions, including the ability to specify that a permission is granted through ALL relations via the intersection (&) operator, or excluded via the exclusion (-) operator.

For example, to grant the can_comment permission only if a user has BOTH the can_view permission and the commenter relation, the following permission definition can be used:

document:
  relations:
    viewer: user
    commenter: user
  permissions:
    can_comment: can_read & commenter
    can_read: viewer

Permissions can also be granted through a hierarchy of object instances by using the arrow (->) operator. For example, to grant the can_read permission through a viewer relation either on a document or the chain of its parent folders, the following permission definition can be used:

folder:
  relations:
    viewer: user
    parent: folder
  permissions:
    can_read: viewer | parent->can_read

document:
  relations:
    viewer: user
    parent: folder
  permissions:
    can_read: viewer | parent->can_read

A user can be granted the can_read permission on a document either explicitly by making them a viewer of that document, or by being granted that permission on a parent folder at any level of the directory tree. This makes it trivial to cascade permissions down a folder hierarchy.

Topaz ReBAC Templates

Topaz 0.31 has a new set of templates that make it easy to get started with some common authorization scenarios: Google Drive (gdrive), Slack (slack), and GitHub (github). Each template provisions three artifacts:

  • a generic authorization policy (policy-rebac).
  • a manifest that models the respective object types, relations, and permissions - for example, users, groups, folders, and documents.
  • domain-specific data, including users, groups, documents, folders, and the relationships between these objects.
  • optionally, a set of assertions (tests) that can be used to verify that Topaz is returning the correct decisions for each assertion.

For example, to instantiate the gdrive template, install Topaz and run the following command. It will configure the policy, set the gdrive manifest, load the data, run the assertions (tests), and open the Topaz console to view the model.

% topaz templates install gdrive

Installing this template will completely reset your topaz configuration.
Do you want to continue? (y/N) y
>>> stopping topaz...
>>> configure policy

certs directory: /Users/ogazitt/.config/topaz/certs

  FILE            ACTION
  gateway.crt     skipped, file already exists
  gateway-ca.crt  skipped, file already exists
  gateway.key     skipped, file already exists
  grpc.crt        skipped, file already exists
  grpc-ca.crt     skipped, file already exists
  grpc.key        skipped, file already exists
policy name: gdrive
>>> starting topaz...
403a793d498bcc45f93b5e0357fe7307f4a6eea383821cf1752e27e1b73d6f77

WARNING: delete manifest resets all directory state, including relation and object data
>>> delete manifest
>>> set manifest from /Users/ogazitt/.config/topaz/model/manifest.yaml
>>> importing data from /Users/ogazitt/.config/topaz/data
        objects 37
      relations 61
0001 check            PASS  folder:root#owner@user:beth@the-smiths.com [true] (7.455666ms)
0002 check            PASS  folder:root#can_read@user:beth@the-smiths.com [true] (578.625µs)
0003 check            PASS  folder:root#can_write@user:beth@the-smiths.com [true] (427.959µs)
0004 check            PASS  folder:root#can_share@user:beth@the-smiths.com [true] (652.375µs)
0005 check            PASS  folder:root#can_read@user:rick@the-citadel.com [false] (1.526709ms)
0006 check            PASS  folder:root#can_write@user:rick@the-citadel.com [false] (454.458µs)
0007 check            PASS  folder:root#can_share@user:rick@the-citadel.com [false] (432.375µs)
0008 check            PASS  folder:root#can_read@user:morty@the-citadel.com [false] (450.917µs)
...

Topaz is fast! After the initial warm-up, most of the decisions using this synthetic dataset complete under 1ms.

Here is the graphical representation of the gdrive manifest, which can be viewed in the Topaz console:

Aserto Graph Directory

ReBAC Quickstarts

Last but not least, the Aserto Console now includes complete tutorials for each of the new templates. To check these out, create an Aserto account if you don’t have one already. To instantiate one of the new templates, follow the new documentation pages for the quickstarts.

Each template comes with a back-end API in six different languages which you can download, install, and run.

Aserto ReBAC Quickstarts

Once the API is running, you can use the testing modal in the quickstart to generate curl commands for some combination of user, operation, and resource, to test out authorization decisions across users, permissions, and resources.

Aserto Google Drive ReBAC template

Once you’ve gotten familiar with the model, you can check out the backend API’s source code to see how easy it is to add authorization to an app in the language of your choice - typically by simply adding some middleware.

Try it out!

To check out Topaz, follow the docs or clone the repo. If you like it, please join our community Slack, where we’ll be happy to answer any questions.

And if you’d like to take a quick peek without installing anything, sign up for a free Aserto account and check out our SaaS version.

Happy Hacking!

Omri Gazitt avatar

Omri Gazitt

CEO, Aserto