oso helps developers build authorization into their applications. If you’ve never used oso before and want to see it in action, this guide is for you. We’re going to walk through how to use oso to add authorization to a simple web server.
Run the server¶
Our sample application serves data about expenses submitted by users. The sample application has three important files.
One file defines a simple
Expense class and some sample data stored in a map.
A second file has our HTTP server code, where we have defined a route handler for
GET requests to the path
/expenses/:id. We’ve already added an authorization check using the oso library to control access to expense resources. You can learn more about how to add oso to your application here.
The third file is the oso policy file,
expenses.polar, and is currently empty.
With the server running, open a second terminal and make a request using cURL:
You’ll get a “Not Authorized!” response because we haven’t added any rules to our oso policy (in
expenses.polar), and oso is deny-by-default.
Let’s start implementing our access control scheme by adding some rules to the oso policy.
Adding our first rule¶
oso rules are written in a declarative policy language called Polar. You can include any kind of rule in a policy, but the oso library is designed to evaluate allow rules, which specify the conditions that allow an actor to perform an action on a resource.
In our policy file (
expenses.polar), let’s add a rule that allows anyone with an email ending in
"@example.com" to view all expenses:
String terms following the colons in the head of the rule are specializers, patterns that control rule execution based on whether they match the supplied argument. This syntax ensures that the rule will only be evaluated when the actor is a string and the resource is an instance of the
Once we’ve added our new rule and restarted the web server, every user with an
@example.com email should be allowed to view any expense:
Okay, so what just happened?
When we ask oso for a policy decision via
Oso.is_allowed(), the oso engine searches through its knowledge base to determine whether the provided actor, action, and resource satisfy any allow rules. In the above case, we passed in
"firstname.lastname@example.org" as the actor,
"GET" as the action, and the
Expense object with
id=1 as the resource. Since
"email@example.com" ends with
@example.com, our rule is satisfied, and Alice is allowed to view the requested expense.
If a user’s email doesn’t end in
"@example.com", the rule fails, and they are denied access:
If you aren’t seeing the same thing, make sure you created your policy correctly in
Using application data¶
We now have some basic access control in place, but we can do better. Currently, anyone with an email ending in
@example.com can see all expenses – including expenses submitted by others.
Let’s modify our existing rule such that users can only see their own expenses:
Behind the scenes, oso looks up the
submitted_by field on the provided
Expense instance and compares that value against the provided actor. And just like that, an actor can only see an expense if they submitted it!
Alice can see her own expenses but not Bhavik’s:
Feel free to play around with the current policy and experiment with adding your own rules!
For example, if you have
User classes defined in your application, you could write a policy rule in oso that says a
Expense if they manage the
User who submitted the expense and the expense’s amount is less than $100.00:
In the process of evaluating that rule, the oso engine would call back into the application in order to make determinations that rely on application data, such as:
Which user submitted the expense in question?
Who is their manager?
Is their manager the user who’s attempting to approve the expense?
Does the expense’s
amountfield contain a value less than $100.00?
For more on leveraging application data in an oso policy, check out Application Types.
Subscribe to our newsletter
Stay up to date with the latest features and updates to oso.