Oso 0.20 is out!
The features in this release have been in the works for a while now, and we're thrilled to finally share them with you all. If you're interested in hearing from our cofounder and CTO on our view on this problem domain and how we are solving it, read his post, Why Authorization is Hard.
0.20 includes new approaches to...
- Authorization modeling - we've introduced built-in policy primitives for specifying permissions, roles, and relationships to simplify common patterns like role- and relationship-based access control (RBAC and ReBAC).
- Data filtering - the ability to authorize collections of data (e.g., show me only the rows that Juno can see) is now available for Python, Node, and Ruby (and any data source!). Go, Java, and Rust support coming soon.
- APIs - Oso 0.20 ships with native APIs for enforcing authorization at different layers of the stack (e.g., request-, resource-, and field-level authorization).
Built-in Primitives for Authorization Modeling
We're introducing several features in 0.20 to improve the experience of modeling your authorization requirements, and implementing that model with Oso.
Our goals for these features were:
- Provide built-in ways to define common authorization models to take the guesswork out of policy writing
- Introduce intuitive organization to policies
- Provide more feedback to developers during the policy writing process
The features we developed to address these goals are resource blocks and rule types.
Role- and Relationship-Based Access Control with Resource Blocks
Resource blocks are a new way to write policies, specifically optimized for modeling roles and relationships. With resource blocks, you can:
- Organize your policy by actor and resource
- Explicitly define roles, permissions, and relations for each resource
- Use the roles, permissions, and relations you defined to write shorthand rules, streamlined rules that eliminate boilerplate and let you focus on authorization logic
Here's what a policy with resource blocks looks like:
allow(actor, action, resource) if has_permission(actor, action, resource);
resource Repository {
permissions = ["read", "push", "delete"];
roles = ["contributor", "maintainer", "admin"];
"read" if "contributor";
"push" if "maintainer";
"delete" if "admin";
"maintainer" if "admin";
"contributor" if "maintainer";
}
has_role(user: User, name: String, repository: Repository) if
role in user.roles and
role.name = name and
role.resource = repository;
Resource blocks are available in every language library, and are compatible with any data model and data store. You can also use resource blocks alongside base Polar rules, providing you with unlimited extensibility.
Some of the things you can model with resource blocks:
- Organization-level roles
- Resource-level roles
- Roles that span resource hierarchies
- Group roles
To start modeling with resource blocks, take a look at our guides on modeling role-based access control or resource hierarchies, or read the reference to learn more about the syntax.
Policy Validation with Rule Types
We wanted to improve the policy writing process by providing developers with more feedback and validation. Rule types specify requirements for rules that are checked when policies are loaded. We've written a set of built-in rule types to ensure correct usage of rules that are evaluated by library APIs or used by built-in features.
Here's an example rule type error:
polar.exceptions.ValidationError: Invalid rule: allow(_actor, _action); Must match one of the following rule types:
allow(actor, action, resource);
Failed to match because: Different number of parameters. Rule has 2 parameter(s) but rule type has 3.
For more information on built-in rule types, check out our docs.
Data filtering from any data source in Python, Ruby, and NodeJS
Over the last six months, we received constant requests to expand data filtering support (previously only in SQLAlchemy and Django) to more languages and frameworks.
This release includes the following updates to data filtering:
- Data filtering is available for Python, Ruby, and NodeJS (Java, Go, and Rust coming soon!)
- It works with any data source (you no longer need specific ORMs to use the feature)!
- A single method to filter data:
authorized_resources(actor, action, type)
returns all the resources of typetype
that theactor
is allowed to take theaction
on - New APIs for registering information about application types and fetching data, so you can customize how Oso retrieves data from your application
To get started, check out our new guide on how to filter data with Oso.
APIs for Resource, Request and Field-level Authorization
This release expands Oso's library APIs to provide specific methods for common authorization enforcement scenarios, to simplify integrating Oso with your application.
Resource-level authorization
authorize(actor, action, resource)
: ensures an actor can perform a particular action on a resource (this is most similar tois_allowed
).authorized_actions(actor, resource)
: returns all actions an actor can perform on a single resource
Request-level authorization
authorize_request(actor, request)
: ensures an actor can send a particular request to the server.
Field-level authorization
authorize_field(actor, action, resource, field)
: ensures that an actor can perform an action on a particular field of a resource.authorized_fields(actor, action, resource)
: returns all the fields of a resource that an actor can take an action on
Read more about our new APIs in our new guide to enforcing authorization.
Other Bug Fixes and Improvements
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.
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.
For more details on these and other changes, you can read the changelog. We've also written a migration guide that explains how to fix breaking changes if you're migrating from an earlier version of Oso.
Set up a 1x1 with an Oso engineer
Our team is happy to help you get started with Oso, or migrate to 0.20 if you on an earlier version. If you'd like to try out any of these new features, or if you're interested in learning how to use Oso in your app, schedule a 1x1 with an Oso engineers.
Our team is also available to help in Slack.