Policies (PolicyDecl)
Generated from the doc schema (CatalogDocSchema, @canonify/kernel-catalog/doc): each field’s type, default and description are the schema’s own, and each example is a bundle file that readBundle decodes. A field’s Example is its value in one of those examples.
PolicyDecl
A policy: who may do what, on which rows and columns (authz).
The policies slot of the doc holds these, keyed by id. In a bundle each is one file, policies/<name>.json, named by its name, which the file then leaves out.
One of, told apart by mode:
PolicyDecl.permit
A permit: grants the operations (the union of every matching permit). A permit adds to the role baselines; it never narrows them. To narrow, write a restrict or a deny.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
id |
PolicyId | yes (propose assigns it; a new declaration leaves it out) | — | — | A policy id (po_…); renames keep it. |
name |
Ident | yes | — | "members_own_orders" |
The policy name. |
label |
Text | yes | — | "Members see their own orders" |
The words shown for it. |
subject |
Subject | yes | — | {"role":"member"} |
Who it applies to. |
on |
ResourceSel | yes | — | {"types":["ty_3f8v6h2n0c"]} |
What it is about. |
ops |
AccessOp[] (at least one) | yes | — | ["read","update"] |
The operations it is about. |
reason |
MsgRef | no | — | {"text":"You can only work on your own orders."} |
What a refusal or a “why” shows for it. |
mode |
"permit" |
yes | — | "permit" |
permit: it grants the operations on the rows and columns it covers. |
rows |
Expr | no | — | "owner == me.member" |
A CX condition over the type’s row and me: the rows it covers. Unknown on a row = not covered; absent = every row. |
check |
Expr | no | — | "owner == me.member" |
A CX condition the row must hold after a create, update or transition (WITH CHECK); absent = the same as rows. |
columns |
ColumnSel | no | — | {"mode":"mask","props":["pr_8b2f4h6j0k"]} |
The columns it shows, masks or hides; absent = every column. |
policies/members_own_orders.json
{
"label": "Members see their own orders",
"mode": "permit",
"subject": { "role": "member" },
"on": { "types": ["ty_3f8v6h2n0c"] },
"ops": ["read", "update"],
"rows": "owner == me.member",
"check": "owner == me.member",
"columns": { "mode": "mask", "props": ["pr_8b2f4h6j0k"] },
"reason": { "text": "You can only work on your own orders." }
}
PolicyDecl.restrict
A restrict: a wall on rows, which every grant must also pass.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
id |
PolicyId | yes (propose assigns it; a new declaration leaves it out) | — | — | A policy id (po_…); renames keep it. |
name |
Ident | yes | — | "drivers_own_region" |
The policy name. |
label |
Text | yes | — | "Drivers stay in their region" |
The words shown for it. |
subject |
Subject | yes | — | {"group":"gr_5r7t9w1y3a"} |
Who it applies to. |
on |
ResourceSel | yes | — | {"types":["ty_3f8v6h2n0c"]} |
What it is about. |
ops |
AccessOp[] (at least one) | yes | — | ["read"] |
The operations it is about. |
reason |
MsgRef | no | — | {"text":"Drivers work only in the north region."} |
What a refusal or a “why” shows for it. |
mode |
"restrict" |
yes | — | "restrict" |
restrict: a wall; whatever else grants the operations, only the rows it covers. |
rows |
Expr | no | — | "region == \"north\" || lines.any(l => l.qty > 0)" |
A CX condition over the type’s row and me: the rows it covers. Unknown on a row = not covered; absent = every row. |
check |
Expr | no | — | "region == \"north\"" |
A CX condition the row must hold after a create, update or transition (WITH CHECK); absent = the same as rows. |
except |
Subject[] (at least one) | no | — | [{"member":"u-01HZY8Q2:person"}] |
The actors it does not bind: an actor any of these names (at its standing and its stored standing alike) passes it. Absent = it binds every actor its subject names. |
direct |
true |
no | — | true |
true: it binds only writes made under the invoker’s own rights; an action that writes with its own rights (writeRights: action) passes it. Only on types and write ops. |
policies/drivers_own_region.json
{
"label": "Drivers stay in their region",
"mode": "restrict",
"subject": { "group": "gr_5r7t9w1y3a" },
"on": { "types": ["ty_3f8v6h2n0c"] },
"ops": ["read"],
"rows": "region == \"north\" || lines.any(l => l.qty > 0)",
"check": "region == \"north\"",
"reason": { "text": "Drivers work only in the north region." }
}
policies/drivers_ship_north_themselves.json
{
"label": "Drivers ship north orders themselves",
"mode": "restrict",
"subject": { "role": "member" },
"on": { "types": ["ty_3f8v6h2n0c"] },
"ops": [{ "transition": "tn_6s8v0x2z4b" }],
"rows": "region == \"north\"",
"except": [{ "member": "u-01HZY8Q2:person" }],
"direct": true
}
PolicyDecl.deny
A deny: a bar on the resource or on some of its columns.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
id |
PolicyId | yes (propose assigns it; a new declaration leaves it out) | — | — | A policy id (po_…); renames keep it. |
name |
Ident | yes | — | "drivers_no_money" |
The policy name. |
label |
Text | yes | — | "Drivers never see money" |
The words shown for it. |
subject |
Subject | yes | — | {"group":"gr_5r7t9w1y3a"} |
Who it applies to. |
on |
ResourceSel | yes | — | {"types":["ty_3f8v6h2n0c"]} |
What it is about. |
ops |
AccessOp[] (at least one) | yes | — | ["read"] |
The operations it is about. |
reason |
MsgRef | no | — | {"text":"Prices are for the office."} |
What a refusal or a “why” shows for it. |
mode |
"deny" |
yes | — | "deny" |
deny: a bar; the operations are refused, on the whole resource or on the columns it names. |
columns |
ColumnSel | no | — | {"mode":"hide","props":["pr_8b2f4h6j0k"]} |
The columns it bars; absent = the whole resource. |
except |
Subject[] (at least one) | no | — | [{"group":"gr_5r7t9w1y3a"}] |
The actors it does not bind: an actor any of these names (at its standing and its stored standing alike) passes it. Absent = it binds every actor its subject names. |
direct |
true |
no | — | true |
true: it binds only writes made under the invoker’s own rights; an action that writes with its own rights (writeRights: action) passes it. Only on types and write ops. |
policies/drivers_no_money.json
{
"label": "Drivers never see money",
"mode": "deny",
"subject": { "group": "gr_5r7t9w1y3a" },
"on": { "types": ["ty_3f8v6h2n0c"] },
"ops": ["read"],
"columns": { "mode": "hide", "props": ["pr_8b2f4h6j0k"] },
"reason": { "text": "Prices are for the office." }
}
policies/members_order_through_actions.json
{
"label": "Members change orders only through actions",
"mode": "deny",
"subject": { "role": "member" },
"on": { "types": ["ty_3f8v6h2n0c"] },
"ops": ["create", "update", "delete"],
"except": [{ "group": "gr_5r7t9w1y3a" }],
"direct": true
}
policies/only_drivers_place_orders.json
{
"label": "Only drivers place orders",
"mode": "deny",
"subject": { "role": "member" },
"on": { "actions": ["ac_3h5k7n9q1s"] },
"ops": [{ "invoke": "ac_3h5k7n9q1s" }],
"except": [{ "group": "gr_5r7t9w1y3a" }]
}
Subject
Who it names: a role, a group, a member, the visitors of an app or form, everyone, or no one (a credential narrowing) (authz Subject, C56).
One of:
Subject.role
The members who hold a role.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
role |
"owner" | "admin" | "member" | "viewer" |
yes | — | "admin" |
The role: its holders, by the role the Forspring account gives them in the org. |
The subject of a policy file (policies/<name>.json), or an approval’s approvers.
{ "role": "admin" }
Subject.group
The members of a group (membership is data: the member list).
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
group |
GroupId | yes | — | "gr_5r7t9w1y3a" |
The group. |
The subject of a policy file (policies/<name>.json), or an approval’s approvers.
{ "group": "gr_5r7t9w1y3a" }
Subject.member
One member.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
member |
string (matching ^[\x21-\x7e]{1,255}$) |
yes | — | "u-01HZY8Q2:person" |
The member, by their Forspring account id. |
The subject of a policy file (policies/<name>.json), or an approval’s approvers.
{ "member": "u-01HZY8Q2:person" }
Subject.carrier
The visitors of a published app or form (carriers; never org members).
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
carrier |
CarrierArtifact | yes | — | {"app":"ap_6c8e0g2j4m"} |
The app or public form whose visitors it names. |
persona |
PersonaId | no | — | "pe_0b2d4f6h8k" |
Only visitors with this persona; absent = every visitor of the artifact. |
The subject of a policy file (policies/<name>.json), or an approval’s approvers.
{ "carrier": { "app": "ap_6c8e0g2j4m" }, "persona": "pe_0b2d4f6h8k" }
Subject.everyone
Every actor of every kind.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
everyone |
true |
yes | — | true |
Every actor: members, services, carriers and declarations. |
The subject of a policy file (policies/<name>.json), or an approval’s approvers.
{ "everyone": true }
Subject.narrowing
A credential narrowing: grants no actor by itself; a capped key holds only what its narrowing permits name (authz.md §2.2 step 7).
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
narrowing |
true |
yes | — | true |
No actor: the permit narrows only the account keys whose DO-side cap names it. |
The subject of a policy file (policies/<name>.json), or an approval’s approvers.
{ "narrowing": true }
CarrierArtifact
A published artifact: an app or a public form.
One of:
CarrierArtifact.app
A published app (internal, external or public).
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
app |
AppId | yes | — | "ap_6c8e0g2j4m" |
The app. |
The carrier of a policy’s subject.
{ "app": "ap_6c8e0g2j4m" }
CarrierArtifact.form
A public form.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
form |
FormId | yes | — | "fm_4n6q8s0v2x" |
The public form. |
The carrier of a policy’s subject.
{ "form": "fm_4n6q8s0v2x" }
ResourceSel
What it is about: types, actions, views, apps, forms, platform data, the catalog or the org.
One of:
- ResourceSel.types
- ResourceSel.actions
- ResourceSel.views
- ResourceSel.apps
- ResourceSel.forms
- ResourceSel.platform
- ResourceSel.catalog
- ResourceSel.org
ResourceSel.types
Rows of types: the only resource a row rule or a column set applies to.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
types |
TypeId[] (at least one) | yes | — | ["ty_3f8v6h2n0c"] |
The types, by id. |
The on of a policy file.
{ "types": ["ty_3f8v6h2n0c", "ty_7k2m9q4z1a"] }
ResourceSel.actions
Actions.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
actions |
ActionId[] (at least one) | yes | — | ["ac_3h5k7n9q1s"] |
The actions, by id. |
The on of a policy file.
{ "actions": ["ac_3h5k7n9q1s"] }
ResourceSel.views
Views.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
views |
ViewId[] (at least one) | yes | — | ["vw_1m3p5r7t9w"] |
The views, by id. |
The on of a policy file.
{ "views": ["vw_1m3p5r7t9w"] }
ResourceSel.apps
Apps.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
apps |
AppId[] (at least one) | yes | — | ["ap_6c8e0g2j4m"] |
The apps, by id. |
The on of a policy file.
{ "apps": ["ap_6c8e0g2j4m"] }
ResourceSel.forms
Public forms.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
forms |
FormId[] (at least one) | yes | — | ["fm_4n6q8s0v2x"] |
The public forms, by id. |
The on of a policy file.
{ "forms": ["fm_4n6q8s0v2x"] }
ResourceSel.platform
Platform data: the audit, record history, the member list, keys or files.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
platform |
("audit" | "history" | "members" | "keys" | "files")[] (at least one) |
yes | — | ["audit","history"] |
The platform relations. |
The on of a policy file.
{ "platform": ["audit", "history"] }
ResourceSel.catalog
The catalog itself (manage_catalog, manage_policy).
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
catalog |
true |
yes | — | true |
The org’s catalog. |
The on of a policy file.
{ "catalog": true }
ResourceSel.org
The org as a whole (members, keys, export, audit, break-glass, erase).
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
org |
true |
yes | — | true |
The org. |
The on of a policy file.
{ "org": true }
AccessOp
An operation it allows or refuses.
One of:
- AccessOp.set
- AccessOp.attach
- AccessOp.transition
- AccessOp.invoke
- AccessOp.approve
"read"|"create"|"update"|"delete"|"open"|"manage_policy"|"manage_catalog"|"manage_members"|"manage_keys"|"export"|"read_audit"|"break_glass"|"pin_clock"|"erase"
AccessOp.set
Set one property of a row (a column write grant).
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
set |
PropId | yes | — | "pr_2k4m6p8r0t" |
The property. |
An item of ops in a policy file.
{ "set": "pr_2k4m6p8r0t" }
AccessOp.attach
Attach a file to one property of a row.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
attach |
PropId | yes | — | "pr_2k4m6p8r0t" |
The file property. |
An item of ops in a policy file.
{ "attach": "pr_2k4m6p8r0t" }
AccessOp.transition
Move a row along one lifecycle transition.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
transition |
TransitionId | yes | — | "tn_6s8v0x2z4b" |
The transition. |
An item of ops in a policy file.
{ "transition": "tn_6s8v0x2z4b" }
AccessOp.invoke
Call one action.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
invoke |
ActionId | yes | — | "ac_3h5k7n9q1s" |
The action. |
An item of ops in a policy file.
{ "invoke": "ac_3h5k7n9q1s" }
AccessOp.approve
Approve a pending call of one action.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
approve |
ActionId | yes | — | "ac_3h5k7n9q1s" |
The action. |
An item of ops in a policy file.
{ "approve": "ac_3h5k7n9q1s" }
ColumnSel
A set of columns and what happens to them.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
mode |
"allow" | "mask" | "hide" |
yes | — | "mask" |
allow: only these columns are shown; mask: these are shown masked; hide: these are not shown. |
props |
PropId[] (at least one) | yes | — | ["pr_8b2f4h6j0k"] |
The properties, by id. |
The columns of a permit or a deny policy file.
{ "mode": "allow", "props": ["pr_2k4m6p8r0t", "pr_8b2f4h6j0k"] }
DeclarerRef
Who declared it: an account or a platform plugin (authz DeclarerRef, C35); recorded by the service.
One of:
DeclarerRef.account
A member: the trigger acts with that member’s live standing.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
account |
string (matching ^[\x21-\x7e]{1,255}$) |
yes | — | "u-01HZY8Q2:person" |
The member who promoted it, by their Forspring account id. |
The declarer of a trigger file (recorded by the service at promote).
{ "account": "u-01HZY8Q2:person" }
DeclarerRef.platform
A platform plugin: the trigger acts within the plugin’s declared manifest.
| Field | Type | Required | Default | Example | Description |
|---|---|---|---|---|---|
platform |
string (matching ^[a-z][a-z0-9_-]{0,63}$) |
yes | — | "esign" |
The platform plugin. |
The declarer of a trigger file (recorded by the service at promote).
{ "platform": "esign" }