oso 0.13.0


Breaking changes

Attempting to create a dictionary with a repeated key is now a parser error. Previously, the first (key, value) pair would be taken and the others would be dropped.


query> d = {a: 1, a: 2}
d = {'a': 1}


query> d = {a: 1, a: 2}
Duplicate key: a at line 1, column 6

Other bugs & improvements

Trailing commas are now supported in dictionaries and lists. For example:

allow(_user, action, repository: Repository) if
  action in [

Node.js & Python

New features

Built-in Role-Based Access Control (RBAC) policy

Oso’s Python and Node libraries now include built-in support for Role-Based Access Control (RBAC) policies. The goal of introducing this feature is to make setting up common role-based access control patterns even easier by providing a structured configuration interface and implementing the query evaluation logic.

Here’s an example policy using the new configuration interface:

resource(_type: Org, "org", actions, roles) if
    actions = ["read", "create_repo"] and
    roles = {
        member: {
            permissions: ["read"],
        owner: {
            permissions: ["read", "create_repo"],

The configuration interface allows Oso users to:

  • Define resource types and roles that are used to control access to individual resources of that type (resource-specific roles)
    • E.g., users can define Organization resources that have "owner", "member", and "billing" roles.
  • Define the actions that each role allows users to take
    • E.g., the "owner" role for an Organization allows users to take the "invite_member" action for that particular organization
  • Define parent-child relationships between resources to enable features like implied roles and nested permissions
    • E.g., if a user has the "owner" role on an organization, they also have the "admin" role implied for every child repository of the organization

In order to use the built-in policy, Oso users must store user-role assignments themselves and implement a simple interface to expose the user-role assignment data to Oso’s policy engine.

Then, the role-based policy will be evaluated as any other policy would by calling the is_allowed() library method.


Breaking changes


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

The Query object returned by Polar::Polar#query is now an Enumerable. Previously, you would need to access the results attribute which was an enumerator.

The main impact of this change is that queries are no longer run on a Fiber, and therefore any methods using Fiber-local variables (e.g. Thread.current[:var]) will work fine.

If you are only using Oso#allowed? there is no change needed.


query = oso.query_rule('allow', actor, action, resource)
first = query.results.next
# raises StopIterator if no results


query = oso.query_rule('allow', actor, action, resource)
first = query.first
# first is nil if there are no results


Other bugs & improvements

Thanks to the ever-helpful @joshrotenberg for a pair of contributions:

  • Making sure the junit dependency doesn’t get packaged in our released JARs ( #964).
  • Starting to align the Java test suite with the other language test suites ( #967).

sqlalchemy-oso 0.9.0

Breaking changes


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

Renamed parent and user_in_role predicates for Role-Based Access Control policies

Two built-in Polar predicates used for implementing Role-Based Access Control have been renamed for clarity and consistency:

  • The parent(child, parent) predicate has been renamed to parent_child(parent, child).
  • The user_in_role(actor, role, resource) predicate has been renamed to actor_can_assume_role(actor, role, resource).

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.