oso 0.20.1

0.20.1 is the next stable release after 0.15.1.

Core

Breaking changes

Warning

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

or / and operator precedence

The or operator has had its precedence lowered to be consistent with other programming languages. Existing policies using or should be updated where necessary to group or operations using parentheses:

foo(a, b, c) if a and b or c;

would now be written

foo(a, b, c) if a and (b or c);

We have temporarily made policies which combine and and or without using parentheses raise warnings in order to avoid silent changes. To silence the error, add parentheses.

New policy loading API load_files. Deprecated load_file

Oso.load_file(file_name) has been deprecated and replaced with Oso.load_files([file1, file2]). Users of load_file will receive a deprecation warning.

Calling load_file, load_files or load_str more than once is now an error.

To migrate rewrite:

oso.load_file("main.polar")
oso.load_file("repository.polar")

as

oso.load_files(["main.polar", "repository.polar"])

load_file will be removed in a future release.

New features

Data Filtering

This release makes data filtering a core library feature. We have added a new method authorized_resources(actor, action, class) that returns all the resources of type class that the actor is allowed to do the action on. It requires registering some new information about classes and implementing some hooks to do the filtering. It is available for Python, Ruby and JavaScript and can be used with any ORM. You can go to the data filtering guide to see how to use it.

Resource blocks for expressing role and relationship based authorization

This release introduces a new, shorthand syntax for declaring roles, permissions, relations, and rules for a particular resource called Resource blocks:

resource Repository {
	permissions = ["read", "push"];
	roles = ["contributor", "maintainer"];

	"read" if "contributor";
	"push" if "maintainer";

	"contributor" if "maintainer";
}

Each of the shorthand rules is expanded into a full Polar rule. For example, "read" if "contributor"; expands into the following rule:

has_permission(actor, "read", repository: Repository) if
  has_role(actor, "writer", repo);

And "contributor" if "maintainer"; expands to:

has_role(actor, "contributor", repository: Repository) if
  has_role(actor, "maintainer", repository);

Read more in the Build Role-Based Access Control (RBAC) guide.

Enforcement API for resource, request and field-level authorization

This release adds new enforcement APIs for more specific enforcement scenarios:

  • authorize(actor, action, resource): ensures an actor can perform a particular action on a resource (this is most similar to is_allowed).
  • authorize_request(actor, request): ensures an actor can send a particular request to the server.
  • authorize_field(actor, action, resource, field): ensures that an actor can perform an action on a particular field of a resource.

Read more about enforcement in the new enforcement guide.

Rust

Other bugs & improvements

  • The rust library now prints messages and warnings directly to stdout and stderr respectively. This means that you can predictably enable Polar tracing by running with POLAR_LOG=1. Fixes issue #824
  • The debugger can now break on rule matches.
  • Polar reserved words (e.g. type, if, debug) can be used as field and method names in dictionaries and objects.
  • Fixed a bug where unifying an external instance with a partially-bound variable in the head of a rule would add an additional constraint to the variable instead of rebinding it to the external instance.

Node.js

Breaking changes

Warning

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

registerClass() API change

The second argument to registerClass() has been changed from a single optional string to an object or Map to accommodate additional optional parameters.

If you weren’t using the second argument, there’s no change required:

// Previously:
oso.registerClass(Foo);
// Still:
oso.registerClass(Foo);

If you were passing a name as the second argument, lift it into the name key of a JavaScript object:

// Previously:
oso.registerClass(Foo, 'Bar');
// Now:
oso.registerClass(Foo, { name: 'Bar' });

django-oso 0.20.1

Other bugs & improvements

  • Updates to maintain compatibility with the core.

sqlalchemy-oso 0.20.1

Other bugs & improvements

  • Updates to maintain compatibility with the core.

flask-oso 0.20.1

Other bugs & improvements

  • Updates to maintain compatibility with the core.

Connect with us on Slack

If you have any questions, or just want to talk something through, jump into Slack. An Oso engineer or one of the thousands of developers in the growing community will be happy to help.