Query Oso Cloud
Querying Oso Cloud returns any facts we can infer that satisfy a given predicate, given the constraints your query specifies.
If that sounds a little vague, it's because querying is a general purpose tool to understand the state of your environment.
Using your SDK to perform queries
All of Oso Cloud's SDKs support arbitrary queries:
Note:
- All of the examples in this document rely on the CLI for simplicity.
- Some SDKs support a more robust query builder. We are in the process of building it for all of our SDKs, but it's still a work in progress.
Quick examples
Before providing a general overview of how queries work in Oso Cloud, here are some straightforward, tactical examples.
In all of these examples, we will use the following policy:
actor User {}resource Organization {}has_permission(user: User, "view", org: Organization) if has_role(user, "member", org);
A few notes about queries:
- You can query for either exact matches to a rule's parameter, or a set of
values using the wildcard operator (
_
). - All of these examples query the
has_permission
rule, but you can query any rule in your policy.
Find an exact match
Specify the exact values you want to find.
For example, does User:alice
have the view
permission on
Organization:acme
?
$ oso-cloud query has_permission User:alice String:view Organization:acme
Find all User
s with a given permission on a Resource
Specify the permission and resource, and use the wildcard operator (_
) for the
User
.
For example, which User
s can "view"
Organization:acme
?
$ oso-cloud query has_permission User:_ String:view Organization:acme
Find all permissions a given User
has on a Resource
Specify the actor and resource, and use the wildcard operator (_
) for the
permission.
For example, which permissions does User:alice
have on Organization:acme
?
$ oso-cloud query has_permission User:alice String:_ Organization:acme
Note that we specify the String
type for the permission because, by
convention, Polar uses String
for permissions.
Find all resources a given User
has a given permission on
Specify the actor and permission, and use the wildcard operator (_
) for the
resource.
For example, which resources does User:alice
have "view"
on?
$ oso-cloud query has_permission User:alice view _
Note that this query will return all resource
s that User:alice
has the
"view"
permission on, not only Organization
s, because the query doesn't
specify any type constraint on the third parameter.
Query global
rules
Polar's global
block lets you
define roles and permissions without specifying a resource––i.e. they are
globally applicable.
To query these rules, you can simply elide the final parameter, which by convention specifies resources.
For example:
- Which
User
s areglobal
"admin"
s?$ oso-cloud query has_role User:_ admin - Does
User:alice
have theglobal
version of the"edit"
permission?$ oso-cloud query has_permission User:alice edit
Note that in most cases, you are unlikely to query global
definitions
themselves. More often, you leverage the global
block in other resource
definitions.
Conceptual overview
Query structure
Polar queries consist of two parts:
-
The predicate to query. Predicates are most easily thought of as the name of rules in your policy.
Each component of a query (i.e. "subquery") contains exactly one predicate.
-
A list of constraints to apply to values that satisfy the query.
Polar considers only instances of the predicate with the same arity (i.e. number of arguments) as the number of constraints supplied to the query.
In pseudo-regex, queries look like:
<predicate> <constraint>+
Constraint structure
Oso offers the following classes of constraints:
Constraint | Description | Format | Example |
---|---|---|---|
Exact value | Constrain parameters to an exact value, which is of a specified type. In the CLI, if you do not specify a Type , Polar assumes the value is a String . | <Type>:<value> | User:alice , read |
Type | Constrain parameters to any value of a specified type. | <Type>:_ | User:_ , String:_ |
Unconstrained | Allow any value of any type | _ | _ |
Note that constraints that specify a type (i.e. Value and Type
constraints) accept only values exactly equal to the constrained type. This is
to say, even if your policy uses Polar's
extends
feature, constraining the
query to a supertype excludes subtype values.
Example
For example, consider this query:
$ oso-cloud query has_permission User:alice String:view Organization:acme
The above query asks Polar: is there any data that causes a has_permission
rule to evaluate to true
, given these constraints:
- Instances of
has_permission
have three parameters - The first parameters must be constrained to equal
User:alice
- Ditto for the second and third parameters for
String:view
andOrganization:acme
respectively
You can also construct more complex queries using wildcards (_
):
-
Which
User
s have theview
permission onOrganization:acme
?$ oso-cloud query has_permission User:alice_ view Organization:acme -
Which permissions does
User:alice
have onOrganization:acme
?$ oso-cloud query has_permission User:alice _ Organization:acme -
Which resources does
User:alice
have theview
permission on?$ oso-cloud query has_permission User:alice String:view _
Query results
In response to a query, Oso Cloud returns all facts Polar is able to construct using the queried predicate that satisfy the specified constraints. We have more detail on what this means below.
An example of a returned fact is:
has_permission User:alice view Organization:acme
If Polar cannot construct any facts, you'll receive:
(no results)
Constructing facts
In logic programming, facts represent rules that are unconditionally true. There are two ways to construct facts in response to a query:
- Literal facts. These may either be:
- Explicit facts defined in your policy
- Any piece of authorization data
- Inferred facts from conditional rules––i.e. Polar can find valid bindings
for a rule's variable parameters such that its conditions are satisfied.
"Bindings" is shorthand for assigning values to a rule's variable parameters,
e.g. binding
User{"alice"}
to the rule'suser: User
parameter.
Inference example
For example, if Oso Cloud receives this query:
$ oso-cloud query has_permission User:alice String:view Organization:acme
Polar tries to find a valid set of bindings to the has_permission
rule, which
we've defined as:
has_permission(user: User, "view", org: Organization) if has_role(user, "member", org);
To determine valid sets of bindings, Polar binds the user
parameter to
User{"alice"}
, and then tries to find instances of has_role
where the user
parameter can also bind to the same value, User{"alice"}
. This is also true of
the org
parameter.
However, the "member"
parameter is already bound, so Polar requires that it
finds a predicate that contains exactly that value. Ultimately, it attempts to
find:
has_role(User{"alice"}, "member", Organization{"acme"})
This should make some sense––our policy said that the permission ("view"
) is
granted based on the user's role ("member"
). To determine this permission, we
check that the user has the specified role. This process is essentially
role-based access control
(RBAC).
If Polar can find such a binding (i.e. validly assign a value to a variable), it remembers the values from the "root predicate" it was searching, and returns them in the query's results, e.g.
has_permission User:alice view Organization:acme
By leveraging authorization data, Polar can infer this to be true, even though it was not explicitly stated in your policy.
Understanding your environment
We use the term environment in this context to refer to the combination of two things, both from your Oso Cloud environment:
- Polar policy, which represents the authorization logic you want to enforce
- Authorization data, which represents the data your authorization logic operates over
We use environment here because each query operates over exactly one environment. Oso Cloud does not support cross-environment queries.
Query vs. other APIs
Querying Oso Cloud is our general-purpose tool to evaluate your authorization data in the context of your Polar policy, and it powers all of our other APIs.
For example, the CLI command oso-cloud authorize
performs a queries the
allow
predicate using the supplied parameters. Oso then determines
authorization based on the number of values returned ((no results)
indicates
the request should be denied).
Talk to an Oso engineer
If you'd like to learn more about using Oso Cloud in your app or have any questions about this guide, schedule a 1x1 with an Oso engineer. We're happy to help.