In today's data-driven world, managing access control and authorization in software systems is paramount. Achieving this task with precision, scalability, and flexibility is no mean feat, considering the multitude of complex relationships and high volumes of data to handle. This blog post dives into a comparative analysis of graph-based and policy-as-code authorization systems, showcasing their pros and cons in diverse scenarios. Our spotlight will be on renowned systems like Google Zanzibar, SpiceDB, Ory Keto, OpenFGA, Open Policy Agent, OSO, and AWS Cedar.
Graph-Based Authorization Systems
Graph-based authorization systems employ a graphical representation to illustrate relationships between users and resources. They excel at mapping hierarchies and nested relationships, offering a natural avenue for Relationship-based Access Control (ReBAC). Given their ability to manage high volumes of data while maintaining consistency, these systems prove effective in large-scale environments.
The inception of graph-based authorization systems can be traced back to Google Zanzibar. Renowned for its distributed, scalable, and consistent architecture, Zanzibar serves as Google's gatekeeper for access control. Underpinning Zanzibar is a graph data model and a distributed consensus algorithm ensuring consistent authorization decisions across the board.
Drawing inspiration from Zanzibar, there’s SpiceDB - a mature open-source graph-based authorization system. Extending beyond the original specifications of Zanzibar, SpiceDB introduces features such as Caveats and adopts the role of a permissions database, emphasizing its centrality in the authorization domain.
Despite their advantages, deploying a Zanzibar-based graph invariably introduces a sizable and complex system into your cloud environment, often necessitating reliance on a hosted service. This dependency can instigate latency concerns and further scaling challenges.
Policy as Code Authorization Systems
In contrast to graph-based systems, policy-as-code authorization utilizes code to define authorization policies, facilitating their modification and offering a higher degree of flexibility. They effectively handle complex rules and relationships, with Open Policy Agent (OPA) and AWS Cedar being prime examples.
OPA, popular across numerous organizations, employs a declarative policy language (Rego) that simplifies the definition of complex authorization policies. AWS Cedar, on the other hand, focuses on application-level authorization, providing a simple policy language that promotes easy readability and analyzability.
Weighing the Pros and Cons
When choosing between graph-based and policy-as-code systems, understanding their strengths and limitations is critical.
Graph-based systems shine in scenarios requiring ReBAC and are adept at describing hierarchical and nested relationships. They ensure data consistency even in high-volume scenarios and offer reverse indices, enabling reverse queries (not only does x have access to y, but also who has access to y).
However, they do come with drawbacks. Compared to policy-as-code, graph-based systems exhibit lower performance and are practically unfeasible to run at the edge due to their size. They also come with higher latency, owing to their non-local nature, and are limited to simple ReBAC policies (even SpiceDB Caveats you end up with a limited form of ABAC, crippled even further with loading dynamic data).
Policy-as-code systems, on the other hand, offer great flexibility and ease of policy update. They're adept at managing complex policies like ABAC and boast a mature ecosystem with a variety of plugins and engines. Despite these advantages, they have their limitations. These systems can struggle with high volumes of data without appropriate sharding, require learning complex languages, and do not support reverse indices.
Nature of Access Control
Natural fit for Relationship-based Access Control (ReBAC)
Excels at managing complex policies (e.g., ABAC)
Representation of Relationships
Excellent for representing hierarchies and nested relationships
Flexible and can manage complex relationships, but not inherently hierarchical
Data Volume Management
Manages high volumes of data consistently
Can struggle with large amounts of data without sharding
Supports reverse indices
Does not support reverse indices
Lower performance compared to policy-as-code
Generally high performance
Deployment at Edge
Practically impossible due to size
Feasible and efficient
Higher due to non-locality
Lower due to local deployment
Ease of Updates
Less flexible for updates
Highly flexible and easy to update
Robust ecosystem with plugins and multiple engines
Can be high due to complex languages
Deciding Factor: Scale vs. Complexity
In our experience, the choice between these two primarily hinges on the scale and complexity of the system in question. For systems catering to fewer than 1 million users requiring complex policies, policy-as-code is a leading option. For those catering to more than 1 million users and relying on simpler policies, graph-based systems are a better fit.
Why Not Both?
But who said you must choose? These systems are highly complementary; where one struggles, the other excels. Marrying these two approaches via an event-driven link like OPAL, topped with abstraction interfaces, provides the best of both worlds. You can leverage a reverse-indexable graph-based database in the cloud as a primary data source, feeding policy-as-code engines at the edge. This configuration allows for complex policy implementation, reduced latency, and consistent large-scale data management, offering a hybrid, versatile solution to the ever-evolving authorization conundrum.
In the vast realm of authorization systems, there is no one-size-fits-all solution. The choice between graph-based systems like Google Zanzibar or SpiceDB and policy-as-code systems like Open Policy Agent or AWS Cedar is not about picking the superior technology, but rather about aligning your selection with the specific needs, scale, and complexity of your environment.
While graph-based systems excel in managing high volumes of data and effectively representing relationships in large-scale applications, policy-as-code systems bring flexibility, ease of policy updates, and proficiency in handling complex policies. Each has its strengths and shortcomings and should be chosen after a careful analysis of the system requirements and the trade-offs you're willing to accept.
Moreover, it's crucial to remember that these systems can be complementary. They can be combined to create a hybrid system that leverages the advantages of both, thereby addressing diverse authorization needs. In the end, the goal is to effectively control access to your services, ensure data privacy, and maintain system integrity, regardless of the authorization strategy you choose.