Skip to main content
Oso Cloud uses the Polar programming language to define authorization logic. When editing policies in the Rules Editor, you’re writing Polar code.

Declarative programming

Polar is a declarative language. Instead of specifying how to compute a result, you describe the conditions under which something is true, and the Polar runtime evaluates it. Polar works like a database: you write rules (similar to inserting data) and later issue queries against those rules. At runtime, the Polar engine evaluates your queries and returns matches based on the rules you’ve defined.

Logic programming

Polar is also a logic programming language. It’s designed to answer questions based on a set of rules. You’ll see this in action in the examples below.

How Polar executes

Info: For the next few examples, we’ll use only the base language, without touching authorization just yet. In Polar, rules are written as statements. For example:
father("SisterBear", "PapaBear");
This defines father("SisterBear", "PapaBear") as true. You don’t need to declare the function, each rule is a standalone fact. You can define multiple rules for the same predicate:
father("SisterBear", "PapaBear");
father("BrotherBear", "PapaBear");
Each statement defines a separate rule. This is similar to adding rows in a table. In Polar, rules are written as statements. For example:
  • father is also true when it’s called on the strings "BrotherBear" and "PapaBear".”
Notice that these rules exist side-by-side. We can have any number of rules that use the father predicate — adding a new rule is much like adding a new database entry.

Querying Polar from Oso Cloud

Info: In the following steps, you’ll create an Oso Cloud account and configure your local environment to work with it.

Add rules

Once you’ve created your account:
  • Go to the Rules Editor
  • Copy the rules we created above and paste them into the editor
  • Add:
father("SisterBear", "PapaBear");
father("BrotherBear", "PapaBear");
  • Click “Deploy”
Now that you’ve added the rules to Oso Cloud, let’s set up your local environment to query them.

Configure the CLI

  • In the Oso Cloud UI, go to Organization Settings → API Keys.
  • Create a new API Key in your current environment.
  • When prompted, set the access level to Read Only.
  • Copy and store the key securely, you’ll use it to authenticate the CLI.
  • Navigate to the Install tab under CLI, and follow the installation instructions for your platform.
  • After installation, verify that the CLI is configured correctly:
  • This command should return your current policy from Oso Cloud:
$ oso-cloud policy
  • If your environment is configured correctly, you’ll see the rules we entered in the Rules Editor:
$ oso-cloud policy
== Policy: <no name> ==
father("SisterBear", "PapaBear");
father("BrotherBear", "PapaBear");

Query examples

Ask if SisterBear’s father is PapaBear:
$ oso-cloud query father "SisterBear" "PapaBear"
father(String:SisterBear, String:PapaBear)
Note: If you’re familiar with logic programming, this means that the predicate father holds for the arguments "SisterBear" and "PapaBear". Reverse the arguments and the result is false:
$ oso-cloud query father "PapaBear" "SisterBear"
(no results)
Order matters. Polar matches based on exact arguments and their positions. Use a wildcard to find all children of PapaBear:
# the `_` character is called a `wildcard`  
oso-cloud query father _ "PapaBear"
father(String:BrotherBear, String:PapaBear)
father(String:SisterBear, String:PapaBear)
The _ wildcard returns all values that make the query true.

Conditional rules

So far, we’ve used rules that are always true—unconditional. You can also define rules that are conditionally true using if. In conditional rules, you can introduce variables—for example: grandchild, grandparent, and parent. Oso Cloud requires all variables to have type annotations. Use syntax like grandchild: String or parent matches String to make types explicit. If you omit these, the system will raise a warning. Here’s a rule that defines a grandfather relationship using two father rules:
grandfather(grandchild: String, grandparent: String) if
  parent matches String and
  father(grandchild, parent) and
  father(parent, grandparent);
To use this rule effectively, add one more fact:
father("PapaBear", "GrandpaBear");
Your full policy should now look like:
father("SisterBear", "PapaBear");
father("BrotherBear", "PapaBear");
father("PapaBear", "GrandpaBear");

grandfather(grandchild: String, grandparent: String) if
  parent matches String and
  father(grandchild, parent) and
  father(parent, grandparent);
Deploy the updated policy in the Rules Editor, then query it:
$ oso-cloud query grandfather "SisterBear" _
grandfather(String:SisterBear, String:GrandpaBear)
Oso Cloud evaluates the rule by matching facts to variables and returns the result. Most rules in Polar follow this statement if condition; pattern. See the other modeling patterns for practical usage.