DEV Community

Matt Irby
Matt Irby

Posted on

SpiceDB HRBAC: A Practical Implementation

While working on an internal tool for managing virtual environments, a feature request added into the tool was the ability to share environments with other users. To implement this securely, we needed a way to determine what level of access a given subject (user) had to a particular object (environment or tenant). Given that we may need various roles for a given object (i.e. admin, editor, and viewer), we needed an authorization layer that could handle hierarchical role-based access control (HRBAC).

To minimize the amount of custom code to handle authorization, we decided to leverage Google Zanzibar for a number of reasons:

  • the Zanzibar design favors for quick writes while offering efficient, low-latency lookups
  • the graph-based model naturally handles nested roles, group membership, and resource hierarchies
  • Zanzibar has been proven to work at scale, lending to an efficient and reliable authorization system

A Zanzibar implementation I was particularly drawn to was AuthZed's SpiceDB. SpiceDB offers a mature, open-source, and actively maintained solution with comprehensive documentation, a flexible and extensible schema model, and Kubernetes support through its dedicated operator, making it straightforward to deploy and manage in production environments.

There are many great articles written on how to configure SpiceDB to handle complex role-based access control, for example this article goes into great depth to discuss relation-based access control (ReBAC). But, I do want to dive into how one can make a hierarchical role-based access control (HRBAC) possible via SpiceDB.

I've created a GitHub repository for this example: (https://github.com/irby/spicedb-hrbac-example)

Consider the following schema:

definition user {}

definition role {
    // A role belongs to a specific tenant
    relation tenant: tenant

    // Users can be assigned to this role
    relation assignee: user

    // Define the hierarchical permissions
    permission admin = assignee
    permission editor = assignee + admin
    permission viewer = assignee + editor
}

definition tenant {
    // Direct role assignments within this tenant
    relation admin_role: role
    relation editor_role: role  
    relation viewer_role: role

    // Computed permissions based on role assignments
    permission admin = admin_role->assignee
    permission editor = editor_role->assignee + admin
    permission viewer = viewer_role->assignee + editor
}
Enter fullscreen mode Exit fullscreen mode

With this schema, we've defined the following relations:

  • A user can be assigned to a tenant via a role
  • A role can be one of the following:
    • admin
    • editor
    • viewer
  • These roles have the following hierarchy
    • an admin inherently has editor and viewer access
    • an editor inherently has viewer access
    • a viewer only has its own access.
  • These roles are tenant-scoped. A role relationship to tenant A is logically separate from a role relationship to tenant B.

While a relatively simple implementation, this gives us enough flexibility to configure the HRBAC we require for our internal tool. Combined with SpiceDB's robust SDKs and APIs, this proof of concept demonstrates that we can achieve scalable, maintainable authorization without the burden of building and maintaining custom logic from scratch.

Top comments (0)