if
), meaning it is always true when its parameters match.
When evaluating rules, Polar uses:
- Other rules in your policy
- Facts in the policy or stored externally (see Facts as data)
Rule construction
A Polar rule has three parts:Part | Definition |
---|---|
Predicate | Rule name. Not required to be unique. |
Parameters | Named, typed variables that may unify with a query. |
Expression | (Optional) Boolean condition describing when the rule is true. |
Text | Part |
---|---|
within | Predicate |
(lower: Integer, upper: Integer, x: Integer) | Parameters |
if lower < x and x < upper | Expression |
Rule evaluation
Polar evaluates a rule when:- Another rule calls it
- A query directly references its predicate
true
using your policy rules and fact data.
Example
Facts:Query | Result |
---|---|
family String:Bernie String:Pat | family(String:Bernie, String:Pat) |
family String:Bernie String:Morgan | family(String:Bernie, String:Morgan) |
family String:Pat String:Morgan | no results |
family String:Bernie _ | family(String:Bernie, String:Pat) family(String:Bernie, String:Morgan) |
family String:K _ | no results |
Typing variables in rules
When joining rules with new variables, explicitly type them withmatches
:
Literal parameters
You can hardcode values in rules:Facts: rules without expressions
Facts are rules without anif
clause. Any matching parameters make them true
.
When writing facts, you might want to consider whether the fact is best served being stored in your policy, or whether you should store it as fact data.
Facts in policies
- Stored in the policy file
- Require policy re-deploy to change
- Best for long-lived, static data
Facts as data
- Stored outside the policy via Oso APIs/clients
- Can be updated without redeploying
- Suitable for dynamic or frequently changing data
Default & custom allow
rules
If your policy has no allow
rule, Polar injects:
allow
.
You can override it with your own allow
rule to apply global logic (e.g., impersonation).
Deny logic
Polar supports deny logic, sometimes referred to as a deny rule or deny override approach. There is no explicitdeny
keyword, use not
inside allow
:
is_banned
fact blocks access, even if other rules allow it.
Singleton variables
A singleton variable is one that appears only once in a rule—it can match any value, and often indicates a mistake. Example:first
is unused because the rule calls person("George", last)
instead of person(first, last)
.
Singletons act like wildcards: they unify with any value if the rest of the rule matches.
To keep an unused parameter, prefix it with _
:
_
is an anonymous variable: always a singleton, never triggers warnings, and is unique each time it appears:
Polymorphism
Polar types support polymorphism. For example,Actor
is a subtype of Resource
, so any Resource
can also be an Actor
. See extends
for details.
Fact limits
Oso Cloud is designed to scale with your data. There’s no fixed limit to the number of facts you can store in Oso Cloud, and the number of context facts you can send along with a request is only limited by a 10 MiB request payload limit.Stored facts
- No fixed limit on the number of facts per environment.
- Scaling is managed automatically by Oso Cloud, you do not need to provision or tune for larger data volumes.
Context facts
- When sending context facts in a request, the only limit is the total request payload size (10 MiB).
- The number of facts you can send depends on their individual size.
Fact argument length limit
- Each argument in a fact must be ≤ 384 bytes.
- See built-in types for more details.