Access
Every call to rules.svc carries its caller’s principal: the user, bot, service or agent its token
names, with the privileges iam holds for them. What the call may do is decided by access rules,
written and evaluated exactly like a data entity’s access rules: an expr expression over the
user.* vocabulary and can(path, action), which asks the product’s privilege catalogue.
rules.svc has no role names of its own. Its defaults ask can("rules.scopes", …), so they work
with whatever roles a product defines.
Actions
Section titled “Actions”| Action | Routes | Default rule |
|---|---|---|
read | GET /rulesets, and each folder or scope it lists; reading and cancelling your own sweeps | can("rules.scopes", "read") |
execute | POST /rules/execute, POST /rule | can("rules.scopes", "read") |
run | POST /rules/run of what the tenant serves | can("rules.scopes", "read") |
draft | POST /rules/run with files: rule text the caller sends | can("rules.scopes", "owner") |
evaluate | POST /rules/evaluate; starting a dry sweep | can("rules.scopes", "read") |
apply | POST /rules/evaluate with apply: true; starting a sweep with apply: true | can("rules.scopes", "read-write") |
manage | reading and cancelling anyone’s sweeps | can("rules.scopes", "owner") |
Privileges rank none < read < read-write < owner, so a caller with owner on
rules.scopes passes every default.
A refusal answers 403 rules-access-denied, naming the action and the scope:
{"error":{"code":"rules-access-denied","context":null,"message":"access denied: apply invoice-routing","meta":null}}A rule that cannot be evaluated, because iam cannot be reached for one, refuses too. It never passes.
What the product must grant
Section titled “What the product must grant”The product’s privilege catalogue needs a rules.scopes leaf, granted to the roles that use rules:
read to run and evaluate them, read-write to apply what they propose, owner to author drafts
and manage everyone’s sweeps. A product with no such grant refuses every call by default.
The system user, which sweeps and data-triggered evaluations run as
(Configuration), needs the same
grants for the work it does: evaluate for a dry sweep, apply for a sweep or an event that
writes.
Refining the rules
Section titled “Refining the rules”A product refines any of the actions in rules/extend/access.yaml; the others keep their
defaults. Each rule sees row.name, the scope or folder the call names, so a rule can single one
out:
access: execute: { language: expr, expression: 'can("rules.scopes", "read") || (user.ptyp == "bot" && row.name == "triage")' } read: { expression: 'can("rules.scopes", "read") && row.name != "pricing"' } apply: { expression: 'can("rules.scopes", "read-write") && row.name != "credit-limits"' }languageisexpr, the default. Any other, an unknown action or key, or an empty expression fails the load of the product’s rules, naming the file.- A product that wants anyone in the tenant to execute its rules says so:
execute: { expression: 'true' }. Nothing is open unless a product writes it. rules/extend/holds rules.svc’s settings and no rules; a.grlthere fails the load.
A rule here is the product’s own and changes with the folder: an edit to access.yaml takes effect
when the tenant’s rules load again.
Every read and write is checked again
Section titled “Every read and write is checked again”Passing rules.svc’s access rule lets a call run a scope. Whatever the scope reads or writes is checked again where the data lives, for the same principal:
| Source | Checked by |
|---|---|
data | data.svc, for the caller’s own token: its access rules, row-level security, and its record of who wrote |
seshat | the product’s access rules and row-level security for the entity, run in-process for the caller |
So a write needs three things, each held by a different party:
- the right to apply the scope (
apply, the product’s access rules here); - the right to write that record where it lives (the entity’s access rules in data.svc);
- the rule author’s declaration of the write in the scope’s
writes(Scopes).
A source that refuses the caller answers 403 rules-source-denied.
Continue with
Section titled “Continue with”- The rules service: the routes.
- Scopes: what a static scope may read and write.
- Rules over data: principals, sources, evaluate, sweeps and events.