0.2.0

Release date: 2020-07-14

Breaking changes

Warning

This release contains breaking changes. Be sure to follow migration steps before upgrading.

New rule syntax

We have made several major changes to Polar syntax used in writing rules to make the policy more intuitive for non-technical policy readers.

  • The if operator is now written as if instead of :=.

  • The and operator is now written as and instead of ,.

  • The or operator is now written as or instead of |.

  • The not operator is now written as not instead of !.

Taken together, these changes produce rules like:

allow(actor: User, "view", resource: Expense) if
    role(actor, "accountant") and
    actor.location = resource.location;

Instead of:

allow(actor: User, "view", resource: Expense) :=
    role(actor, "accountant"),
    actor.location = resource.location;

New features

Class methods

Methods can now be called on application classes. For example, with a class called Foo:

my_rule(x) if Foo.class_method(x) = true;

Rest operator for lists

Lists can now be destructured using the *rest operator. This allows statements like:

[x, *rest] = [1, 2, 3]

x would be assigned to 1, and rest to [2, 3].

More information here: *rest Operator.

Language support for anonymous variables

A variable named _ is now recognized as an anonymous variable. Previously, multiple anonymous variables in a rule needed to be named distinctly (_, __, ___). This scenario is often encountered when writing rules with specializers that do not use the argument value:

allow(_: User, "view", _: Resource);

Host language list, string, dictionary and number methods

Because your application objects probably use your language’s built-in primitive types such as str, dict, and int, Polar allows you to use methods on those types for its built-ins, too. That way you can use familiar methods like str.startswith() on strings regardless of whether they originated in your application or as a literal in your policy. This applies to all of the Polar primitive types: strings, lists, dictionaries, and numbers, in any supported application language.

More info: Built-in Types.

Stack traces for runtime errors

Now errors occurring during execution of Polar code will include context about where the issue occurred. The stack_trace property on exception types contains a formatted traceback indicating where errors happened:

trace (most recent evaluation last):
  in query at line 1, column 1
    allow(1)
  in rule allow at line 5, column 13 in file stack-trace.polar
    call_failing_rule(_x_18)
  in rule allow at line 5, column 13 in file stack-trace.polar
    call_failing_rule(_x_18)
  in rule call_failing_rule at line 3, column 25 in file stack-trace.polar
    failing_rule(_x_21)
  in rule call_failing_rule at line 3, column 25 in file stack-trace.polar
    failing_rule(_x_21)
  in rule failing_rule at line 1, column 20 in file stack-trace.polar
    _x_24 in 2
  in rule failing_rule at line 1, column 20 in file stack-trace.polar
    _x_24 in 2

Singleton variable warnings

The usage of a variable only once will now emit a warning on standard error. These often indicate logical errors. This warning can be silenced by prefixing a variable with an underscore. More information: singleton variables.