Distributed Authorization Reference
This guide serves as a detailed configuration reference. For a more general overview, see the guide on filtering lists with decentralized data.
Distributed Check API
The distributed check API allows you to perform authorization using data that's distributed across Oso Cloud and your own database.
The methods are documented under the appropriate Client SDK:
Configuration
The distributed check API requires a YAML file to configure how Oso looks for authorization data in your database. This configuration generally looks like:
# One entry per fact signature in your databasefacts: # Ex: # has_relation(Issue:_, parent, Repository:_): <predicate> ([<type>:]{_, <id>} )*: # Ex: # query: SELECT id, repository FROM issues query: <sql_query># Optional map of resource <type>s to their data type in your application databasesql_types: # Ex: # Issue: UUID <type>: <sql_data_type>
In describing each of these sections, we'll mention various restrictions on each. You can validate that your data bindings don't violate any of these with the oso-cloud CLI
facts
The facts
section is required and is where the majority of your configuration
logic lives. It consists of one key for each fact signature stored in your database.
Fact signatures are specified with a predicate (e.g. has_role
, has_relation
etc.)
followed by a parenthesized list of common separated arguments (e.g. User:_
, String:admin
etc.).
Each fact signature must have a query
value, which specifies the sql query that
will be used to look up facts matching this signature.
The _
symbol in a fact signature indicates that the <id>
of the entity is a variable returned by
the query
. For example, the signature
has_relation(Issue:_, String:parent, Repository:_):
says: "this sql query returns one row for every Issue
that has a parent Repository
".
The query
value for a signature must return the same number of columns as
there are wildcards in the signature. This means that for the signature above, this
SELECT issue.id, 'parent', issue.parent_repoFROM issue
is invalid. A valid query would be
SELECT issue.id, issue.parent_repoFROM issue
Additional Restrictions
Fact signatures must be used by rules in your policy (they wouldn't do much if they didn't).
Fact signatures also must not "overlap", meaning they must all be mutually exclusive. Consider this example:
facts: is_protected (Repository:_, Boolean:true): query: |- select id from repository where is_protected is_protected (Repository:_, Boolean:false): query: |- select id from repository where !is_protected
These facts don't overlap, so this is valid! On the other hand:
facts: is_protected (Repository:_, Boolean:_): query: |- select id, is_protected from repository is_protected (Repository:_, Boolean:false): query: |- select id from repository where !is_protected
These facts do overlap. Slightly more formally the set of facts matching the signature
is_protected (Repository:_, Boolean:_)
contains the set of facts matching the signature
is_protected (Repository:_, Boolean:false)
.
Additionally each query
must be a SELECT
statement (Technically a <query specification>
per SQl-92 (opens in a new tab)).
Common table expressions (CTEs), subqueries, and set expressions like UNION
are allowed,
but each of these must also be a SELECT
. The following is not valid, because the CTE is an UPDATE
statement:
WITH inserted as ( update issue set parent_repo = 1 returning id, parent_repo)SELECT id, parent_repoFROM inserted
sql_types
The sql_types
section is optional, but strongly recommended. It maps resources in
Oso Cloud (e.g. Issue
, Repository
) to their data types in your application database.
This allows authorization queries returned by the distributed check API to more
effectively use indexes, improving query performance.
Example
facts: has_relation(Issue:_, parent, Repository:_): query: SELECT id, repository FROM issuessql_types: Issue: UUID Repository: UUID
This example tells Oso that has_relation
facts that associate issues with their parent repositories
are resolved by running a query (SELECT id, repository FROM issues
) against your application's
database, rather than by looking them up directly in Oso Cloud.
For more information, see the guide on filtering lists with decentralized data.
For a comprehensive example, check out our Ruby on Rails sample app (opens in a new tab)