Infera Policy Language
A declarative language for modeling entities, relationships, and permissions.
IPL defines your authorization model: entity types, their relationships, and derived permissions.
Basic Structure
type user {}
type team {
relation member
}
type organization {
relation admin
relation member
}
type document {
relation parent
relation viewer
relation editor
relation owner
relation can_view = viewer | editor | owner
relation can_edit = editor | owner
relation can_delete = owner
}
Types
Types represent entities in your system. Names must be alphanumeric (plus underscores), starting with a letter.
Relations
Direct relations are stored as tuples. Computed relations derive access from expressions:
relation editor // direct
relation can_view = viewer | editor | owner // computed
Expressions
| Operator | Name | Grants access when… |
|---|---|---|
\| |
Union | any branch matches |
& |
Intersection | all branches match |
- |
Exclusion | base matches and exclusion does not |
relation can_view = viewer | editor | owner
relation can_view_sensitive = viewer & has_clearance
relation can_view_safe = viewer - blocked
Tuple-to-Userset (from)
Follow a relation to a related object, then check a relation there:
type document {
relation parent // points to a folder
relation inherited = viewer from parent // inherit viewer from parent folder
}
If document:readme → parent → folder:specs, and user:alice is a viewer of folder:specs, then Alice has inherited on document:readme.
Related Object Userset (->)
relation computed = parent->can_edit // follow parent, evaluate can_edit there
WASM Module
Invoke a sandboxed WebAssembly module for custom logic:
relation access = viewer & module("business_hours")
Grouping
Use parentheses for precedence:
relation can_view = (viewer | editor) & module("check_ip")
Forbid Rules
Forbid rules are explicit deny — evaluated before all permits and override them unconditionally:
type document {
relation viewer
forbid suspended // denies access even if viewer matches
relation can_view = viewer
}
Wildcards
Grant access to all entities of a type with type:*:
inferadb relationships add "user:*" viewer document:public-faq
Validation
Three validation passes run before deployment:
- Type checking — references resolve, no undefined relations, cycle detection
- Conflict detection — no permit-forbid conflicts on the same relation
- Coverage analysis — unused relations and uncovered permissions
inferadb schemas validate schema.ipl
inferadb schemas push schema.ipl
Comments
Single-line comments with //:
type document {
relation viewer // anyone with explicit view access
relation editor // can also view (via can_view)
relation can_view = viewer | editor
}