Intro to Polar

Intro to Polar + Oso

In this guide, we'll cover:

  • Basic authorization policy construction
  • Managing facts stored in Oso Cloud
  • Using the oso-cloud binary to understand how authorization will work in your application

Note that this is meant only to be a simple tutorial. This guide does not include best practices for using Oso in production!


To get started, you'll need a few things:

Be mindful when choosing which environment you want to use through the CLI. This tutorial asks you to add facts to your Oso account, which you will likely want to delete when you're done.

Frame of reference

Every Oso deployment consists of a policy, data, and a client. The shortest way to describe Oso is in these terms: Oso makes authorization decisions based on your policy with the data it's been provided whenever a client asks.

In this tutorial, we'll store our policy in Oso Cloud, and then make some other decision's for simplicity's sake:

ComponentTutorial version
DataWe'll store all data in your Oso Cloud's centralized database. This is convenient, but does not necessarily reflect what you will do when using Oso in production.
ClientRather than using a full-fledged application, we'll use oso-cloud tool to interact with the Oso Cloud API.

These are decisions we're making simply because this is a tutorial. In production, you will almost certainly make other choices.

Build a policy

Policies contain the rules you want Oso to abide by when making authorization decisions, such as "only admins and account owners can edit accounts." All users (including you!) write policies in Polar.

Define resources

When building a policy, a good place to start is to determine the objects that exist in your domain model (which is a fancy way of saying how you express what your application does within Polar).

Here's an example of a bare bones policy that only defines objects.

actor User {}
resource Organization {}

To follow along, enter the Oso Cloud Rules editor (opens in a new tab), and paste in the policy.

In Polar, we refer to these as "resources." You can define resources with this kind of syntax:

(actor|resource) <ResourceName> {}

This is to say you define whether the resource is an actor or a resource, give the resource a name, and then end the definition with curly braces. In this tutorial, we won't bother with placing anything inside the curly braces, though rest assured they serve a purpose.

What's the difference between actor and resource?

In short, actors represent the "who" of your policy and resources represent the "what". When your client makes an authorization request, it's typically asking, "Can this actor perform some action on this resource?"

We call both actors and resources "resources" because actors are just a special type of resource. This shouldn't affect much for you right now, but if you are curious, see Polar: Polymorphism.

Define rules

Now that you have resources in your policy, you can describe rules to correlate them. For this tutorial, we'll model these resources as having role-based access control (RBAC).

In an RBAC model, you assign each user a set of roles which determine the actions they may perform on resources.

To model an RBAC relationship, you can define a few rules:

# Members can view organizations
has_permission(user: User, "view", organization: Organization) if
has_role(user, "member", organization);
# Admins can edit organizations
has_permission(user: User, "edit", organization: Organization) if
has_role(user, "admin", organization);
# Admins inherit all permissions from members
has_role(user: User, "member", organization: Organization) if
has_role(user, "admin", organization);

You can paste these right below the lines defining Actor and Resource, and then Deploy the policy.

You might be able to infer this, but defining a rule requires:

  • A name (also known as a predicate)
  • A set of arguments to evaluate whether or not the rule passes
  • A conditional expression to evaluate if the rule passes or not

A few notes might help you understand these rules a little more clearly:

  • Rules often follow something akin to the subject verb object format common in English. For example, has_permission(user: User, "view", organization: Organization) is equivalent to a rule stating "Users (subject) can view (verb) an organization (object)", followed by a qualification.
  • While your rules' actors and resources are defined in the policy, actions and roles just use literal strings. As you work with Polar more, you'll see this convention used everywhere.

That's it for the policy; you'll now learn more about managing data used to make authorization decisions.

Use authorization data

With your policy deployed, use the oso-cloud CLI to make an authorization request. We'll see if the user Alice can view the organization Acme.

oso-cloud authorize User:alice view Organization:acme

You'll receive a Denied response. Why? Oso is a pessimistic system and without knowing anything about the user Alice, Oso will not authorize them to do anything. In fact, with our given policy, Oso will not authorize anything at all until we start providing data.

Facts as data

Facts are simply rules that are unconditionally true. For example, you could imagine a fact:

capital_city("New York", "Albany");

You'll know that it's a fact because the last argument to the predicate isn't followed by an if clause.

Given the RBAC model in your policy, you'll need to provide facts expressing the roles that users have at an organization. We can do this with oso-cloud through the tell subcommand.

oso-cloud tell has_role User:alice admin Organization:acme

You can ensure the client wrote the fact using the get subcommand, which returns all facts from an environment.

oso-cloud get

Where should I store facts?

You might have noticed that facts look like rules, and that rules are stored in your policy. Does that mean you should store facts in your policy?

In short, no. While you could place facts in your policy, it isn't ideal. For example, you wouldn't want an admin account to have to deploy your policy every time a new user signs up.

Instead, Oso expects you to manage facts as data. That can take many different shapes, as we explain and explore throughout the docs. For simplicity in this tutorial, though, we'll simply store the facts in a database available inside your Oso account.

Authorize requests using data

Now that your account has fact data in addition to its policy, we can begin authorizing requests.

Try your last request again, authorizing Alice to view Acme.

oso-cloud authorize User:alice view Organization:acme

You'll receive an Allowed response. But why is that?

As you learned earlier, Polar is a logic programming language, which means it's able draw inferences based on your rules and data. In this case:

  • We want to see if User:alice has the view permission on Organization:acme.
  • Users have the view permission on an organization if they have the member role.
  • Users have the member role if they have the admin role on the organization.
  • User:alice has the role admin on Organization:acme.

This means that Polar was able to infer through a series of rules that User:alice's role of admin grants her the view permission on Organization:acme.

What about the delete action?

oso-cloud authorize User:alice delete Organization:acme

You'll receive the Denied response because Polar doesn't know anything about delete actions; it defaults to prohibiting anything you haven't allowed in your policy.

You can imagine the same scenarios for users without roles, or roles that are not referenced in the policy, or on organizations which the user does not have a role on. The number of things that are disallowed is nearly endless––that's how Oso keeps your application safe.

Clean up

Because we added facts to your account's centralized fact database, you likely want to remove them. The simplest and most precise way is through the Oso Cloud UI.

  1. Go to the Facts tab in Oso Cloud (opens in a new tab).
  2. Click the fact has_role(User, "admin", Organization).
  3. Next to the facts you want to remove from your account, click Delete.

Up Next