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 Users with a given permission on a Resource

Specify the permission and resource, and use the wildcard operator (_) for the User.

For example, which Users 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 resources that User:alice has the "view" permission on, not only Organizations, 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 Users are global "admin"s?

    $ oso-cloud query has_role User:_ admin

  • Does User:alice have the global 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:

ConstraintDescriptionFormatExample
Exact valueConstrain 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
TypeConstrain parameters to any value of a specified type.<Type>:_User:_, String:_
UnconstrainedAllow 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 and Organization:acme respectively

You can also construct more complex queries using wildcards (_):

  • Which Users have the view permission on Organization:acme?


    $ oso-cloud query has_permission User:alice_ view Organization:acme

  • Which permissions does User:alice have on Organization:acme?


    $ oso-cloud query has_permission User:alice _ Organization:acme

  • Which resources does User:alice have the view 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:
  • 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's user: 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.

Get started with Oso Cloud →