- Rules + Facts: Writing facts inside policy files
Fact construction
Facts stored as data follow these rules:- They must be unconditionally true, no
if
clauses. - Arguments must be either primitives (e.g.
3
,"two"
) or object literals (e.g.User{"alice"}
).
Type inference
Oso infers the expected types of facts based on their usage in policy rules. For example:are_friends
facts must take two arguments: a User
and a Dog
.
Based on inferred types, Oso will:
- Reject facts with mismatched types (e.g.,
are_friends(User:alice, Rabbit:peter)
) - Reject facts with missing arguments (e.g.,
are_friends(User:alice)
) - Reject facts with unrecognized predicates (e.g.,
ar_frens(User:alice, Dog:fido)
)
Declaring unused fact types
If you want to store facts that aren’t currently used in your policy—e.g., tagging users or resources—you must declare the allowed type signature usingdeclare
:
has_tag(User:alice, Tag:is-cool)
, even if the policy does not use this fact type.
You can declare the same fact with different argument types using multiple declare
statements:
declare
statements form a union type. Oso will accept any fact that matches one of the declared or inferred types.
You do not need to use declare
for fact types already referenced in your policy, its only required for types your policy does not use. Most policies do not require any declarations.