Enforce authorization in Python

In Model your authorization logic you defined an authorization policy. In this guide, we will cover using Oso’s enforcement API to accept or reject requests based on the policy.

The allow rule

At the end of Model your authorization logic we defined an allow rule. The allow rule is used for resource-level enforcement. It accepts three arguments: an actor (who is making the request), an action (what the actor wants to do), and a resource (the object that the actor wants to perform the action on).

Here’s the allow rule you wrote:

allow(actor, action, resource) if
	has_permission(actor, action, resource);

This rule succeeds if the actor has_permission to perform action on resource. actor, action, and resource are all variables. They are provided when you query the policy.

Querying the policy

The Oso library queries the policy with inputs from your application. To construct a query, you give a rule name and a list of parameters. The query returns a result for every rule that succeeds for the parameters specified. If there are multiple rules that succeed, multiple results will be returned. If no rules succeed, no results are returned from the query.

To enforce authorization, we query for the allow rule with a specific actor, action, and resource.

authorize

The authorize method queries the allow rule. If the query doesn’t have any results (no rules succeed), it throws an authorization error. You should handle this exception and return an error response to the user.

The authorize method should be called any time you want to check if a user can perform an action—-like “read” or “delete”-—on a resource.

Here’s an example of using authorize to check if a user can "read" a repository.

routes.py
@app.route("/repo/<name>")
def repo_show(name):
    repo = Repository.get_by_name(name)

    try:
        oso.authorize(User.get_current_user(), "read", repo)
        return f"<h1>A Repo</h1><p>Welcome to repo {repo.name}</p>", 200
    except NotFoundError:
        return f"<h1>Whoops!</h1><p>Repo named {name} was not found</p>", 404

The user and repository parameters are Python objects. Oso knows about fields & methods on Python objects, and their types, so you can access this data directly from your policy. You used the roles property of the user object in the has_role implementation.

What’s next

Add more authorize calls throughout your application, wherever you read or write data on behalf of a user.

We only covered one type of enforcement in this guide: resource-level enforcement. Oso can also enforce access to fields on an object, requests, or queries from an external data source. See How to: Enforce authorization for more.

This is all you need have Oso setup in your application and authorizing requests. Next, you may want to:

Connect with us on Slack

If you have any questions, or just want to talk something through, jump into Slack. An Oso engineer or one of the thousands of developers in the growing community will be happy to help.