Quickstart
Installing the library
Entitled can be installed with either Pip or Poetry. Other setup tools have not been tested.
pip install entitled
# With Poetry
poetry install entitled
Building your first policy
Policies in Entitled are the elements that contain your authorization logic. They have two essential components:
- A type of resource, essentially any Python type that defines a resource in your application.
- A set of Rules
, essentially Python fonctions matching a specific Protocol that defines the actual decision-making logic.
Defining a Policy
Declaring a new Policy is very simple. The constructor only requires a type parameter.
import entitled
post_policy = entitled.Policy[Post]()
This defines a Policy
on the Post
resource type. This is important, because Entitled will use this
to infer which policy to use whenever it has to make an authorization decision (more on that later!)
Adding rules
Rules represent the actual authorization logic of your app.
A Rule can represent any assertion on your application, whether it is checking for relationship between an actor and a resource or actually evaluating permissions on a resource.
Rules are essentially Python function with a specific signature. To declare a Rule
, you can use a decorator provided by a previously declared Policy
import entitled
auth_client = entitled.Client()
@post_policy.rule("edit")
def can_edit_post(actor, resource: Post, context) -> bool:
return resource.owner == actor
The @policy.rule
decorator automatically registers the decorated function as a rule bound to the given policy object. The string parameter passed represent the label that will be used to call on this rule.
The context
parameter is made available as a tool to provide additional context info that can simply be determined from the (resource, actor) tuple. More on that later.
Making authorization decisions
The Client
While you can technically call Policies directly, you will want to use an instance of Client
class.
import entitled
auth_client = entitled.Client()
This client will serve as your single source of truth for all your authorization decisions. Once it is declared, you can register policies on it using the register()
method.
auth_client.register(post_policy)
Manually registering policies may sound cumbersome... and rightfully so. Entitled provides a mechanism to auto-discover and register policies. More on that later.
Making decisions
Once your policies are registered, making authorization decisions is extremely simple! The Client
object provides the allows
function to evaluate a rule. This function takes as parameters the name of the rule you want to authorize, an actor, a resource and optionally a context dictionary.
if auth_client.allows("edit", actor, resource):
# Your application logic...
The allows
functions returns a boolean indicating whether the actor can perform the given action.
If you want, you can also make use of the authorize
methods that will automatically raise an AuthorizationException
if the user is not allowed to perform the action. Both function are called the exact same way.
Wrapping things up
That's it for the absolute basics of Entitled! But we barely scratched the surface here, as the library offers many more features, including but not limited to :
- Resource-bound policies, or how to group your rules around a specific resource type.
- Auto-discovery of policies.
- Answering the question "What can this actor do?"
Check out the detailed documentation!