Polar Language Reference

Reference guides for the Polar policy language.

Polar Syntax

A brief description of the core syntax elements of Polar.

Python Types in Polar
Working with Python Types Oso’s Python authorization library allows you to write policy rules over Python objects directly. This document explains how different types of Python objects can be used in Oso policies. Note More detailed examples of working with application classes can be found in our Guides. Class Instances You can pass an instance of any Python class into Oso and access its methods and fields from your policy (see Application Types). Python instances can be constructed from inside an Oso policy using the new operator if the Python class has been registered using either the register_class() method or the polar_class() decorator. An example of this can be found here. Numbers and Booleans Polar supports integer and floating point real numbers, as well as booleans (see Primitive Types). These map to the Python int, float, and bool types. Strings Python strings are mapped to Polar strings. Python’s string methods may be accessed from policies: allow(actor, action, resource) if actor.username.endswith("example.com"); user = User() user.username = "alice@example.com" assert(oso.is_allowed(user, "foo", "bar)) Warning Polar does not support methods that mutate strings in place. E.g., capitalize() will have no effect on a string in Polar. Lists Python lists are mapped to Polar lists. Python’s list methods may be accessed from policies: allow(actor, action, resource) if actor.groups.index("HR") == 0; user = User() user.groups = ["HR", "payroll"] assert(oso.is_allowed(user, "foo", "bar")) Warning Polar does not support methods that mutate lists in place. E.g. reverse() will have no effect on a list in Polar. Likewise, lists constructed in Polar may be passed into Python methods: allow(actor, action, resource) if actor.has_groups(["HR", "payroll"]); class User: def has_groups(self, groups): """ Check if a user has all of the provided groups. """ for g in groups: if not g in self.groups: return False return True user = User() user.groups = ["HR", "payroll"] assert(oso.is_allowed(user, "foo", "bar)) There is currently no syntax for random access to a list element within a policy; i.e., there is no Polar equivalent of the Python expression user.groups[1]. To access the elements of a list, you may iterate over it with the in operator or destructure it with pattern matching. Dictionaries Python dictionaries are mapped to Polar dictionaries: allow(actor, action, resource) if actor.roles.project1 = "admin"; user = User() user.roles = {"project1": "admin"} assert(oso.is_allowed(user, "foo", "bar)) Likewise, dictionaries constructed in Polar may be passed into Python methods. Iterables You may iterate over any Python iterable, such as those yielded by a generator, using Polar’s in operator: allow(actor, action, resource) if "payroll" in actor.get_groups(); class User: def get_groups(self): """Generator method to yield user groups.""" yield from ["HR", "payroll"] user = User() assert(oso.is_allowed(user, "foo", "bar)) None The Python value None is registered as the Polar constant nil. If a Python method can return None, you may want to compare the result to nil: allow(actor, action, resource) if actor.get_optional() != nil; class User: def get_optional(self): """Return something or None.""" if self.some_condition(): return self.some_thing else: return None user = User() assert(oso.is_allowed(user, "foo", "bar)) Python → Polar Types Summary Python type Polar type int Integer float Float bool Boolean list List dict Dictionary str String