Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion content/docs/automation/hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ A hook's `ctx.api` runs with the context of the write that **fired** it. That is
| `runAs` | The hook's `ctx.api` runs as |
|:---|:---|
| `'inherit'` *(default)* | the context of the triggering write — the behaviour every hook had before this key existed. |
| `'system'` | elevated: a full-access, RLS-bypassing system principal. Row and field permissions do not apply, and the static `readonly` strip is skipped. |
| `'system'` | elevated: an RLS-bypassing system principal. Row and field permissions do not apply, and the static `readonly` strip is skipped. Elevation stops at identity assignment: an insert, update, delete, transfer, restore or purge of `sys_user_position`, `sys_user_permission_set`, `sys_invitation` or `sys_member` from an app-authored hook's system context (`runAs: 'system'`, a system context it inherits, or `ctx.api.sudo()`) is refused with `PERMISSION_DENIED`, and a `runAs: 'system'` hook whose `language: 'js'` body writes one of them by name through `ctx.api.object('…')` is refused when it is saved — grant positions and permission sets from a hook with `runAs: 'user'`, so the delegated-administration gate judges the user it acts for, and change invitations and memberships through the organization endpoints the refusal names ([row 1b](/docs/permissions/system-context#1-authorization-and-scoping)). |
| `'user'` | the triggering **user**, so the hook can never exceed that user's grants. A hook fired by a write that carried no user has no identity to scope to, so its `ctx.api` data operations are **refused** (`HOOK_UNSCOPED_DATA_ACCESS`) rather than run unscoped. |

```ts
Expand Down
14 changes: 12 additions & 2 deletions content/docs/ui/actions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,18 @@ is a spec proposal for a properly named key, not a values map under this one.

An action body and a registered handler both run **elevated**: `ctx.api` and
`ctx.engine` carry `isSystem`, so they bypass row- and field-level security by
design (that is what lets an action do work the caller cannot do directly). The
consequence is that any caller-specific rule has to be re-established **inside**
design (that is what lets an action do work the caller cannot do directly).
Elevation stops at identity assignment: an insert, update, delete, transfer,
restore or purge of `sys_user_position`, `sys_user_permission_set`,
`sys_invitation` or `sys_member` from either is refused with
`PERMISSION_DENIED`, and a `type: 'script'` action whose body writes one of them
by name through `ctx.api.object('…')` is refused when it is saved — make a
position or permission-set grant from a flow whose `runAs` is `'user'`, which an
action of `type: 'flow'` runs as the invoking user so the
delegated-administration gate judges that user, and change invitations and
memberships through the organization endpoints the refusal names
([row 1b](/docs/permissions/system-context#1-authorization-and-scoping)). The
other consequence is that any caller-specific rule has to be re-established **inside**
your handler — and the predicate most people reach for first does not work:

```js
Expand Down
Loading