AppSpring Docs

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

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

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" }

This page as Markdown