Rules & Modalities
Permissions, prohibitions, obligations, recommendations, priorities.
The core relation of OrBAC:
Rule(organization, role, activity, view, context, modality), stored in
morbac.rules.
INSERT INTO morbac.rules (org_id, role_id, activity, view, context_id, modality, scope)
VALUES (
(SELECT id FROM morbac.orgs WHERE name = 'Clinique Valmont Nord'),
:physician_role_id,
'prescribe', 'prescriptions',
(SELECT id FROM morbac.contexts WHERE name = 'always'),
'permission',
'subtree'
);The four modalities
| Modality | Effect |
|---|---|
permission | grants the action when it applies |
prohibition | denies the action; wins ties against permissions |
obligation | records a duty; informational, listed by pending_obligations() |
recommendation | records advice; listed by pending_recommendations() |
Only permissions and prohibitions participate in the allow/deny decision. Obligations and recommendations never block anything; they surface duties for your application to display or enforce (recipe).
Priority and conflict resolution
priority is an integer, NULL meaning 0. At decision time the engine finds
the highest-priority applicable prohibition and the highest-priority
applicable permission, then:
- no prohibition: allowed if any permission applies;
- prohibition present: allowed only if a permission has strictly higher priority.
Equal priorities deny: ties go to prohibition. The engine fails closed.
Scope and validity
scopewidens the rule across the org tree (self,subtree,lineage, ...) and is resolved at query time; see Organizations.valid_from/valid_untilbound the rule in time. A trigger maintainsis_active, andis_rule_valid()re-checks at decision time, so expiry needs no cron job.
The four rule stores
is_allowed consults four tables, in a fixed order, all with the same
modality and priority semantics:
| Store | Keyed by | Typical use |
|---|---|---|
rules | org + role | the normal case |
cross_org_rules | source org + role, target org | auditors reaching into subsidiaries |
user_rules | user + org | one-off grants or per-user suspensions |
global_rules | user (or all users) | wildcard admins, instance-wide bans |
The exact evaluation order is specified in
is_allowed. Conflicting writes are detected
eagerly: inserting a rule that contradicts an existing one raises a warning
listing the conflicts (detect_rule_conflicts).