Rename the coarse gate from role to permission, matching RBAC

This commit is contained in:
2026-08-03 17:02:47 +02:00
parent 41c568796c
commit 925debbd51
79 changed files with 744 additions and 738 deletions
+8 -8
View File
@@ -1,6 +1,6 @@
# Admin — the system-administration plugin
The Users / Groups / Roles / OAuth2-clients screens for running Plainpages itself. These used to be
The Users / Groups / Permissions / OAuth2-clients screens for running Plainpages itself. These used to be
built into the core; they now ship as a **drop-in example plugin** so a fresh clone has no admin GUI
until you opt in. Copy this folder into `plugins/` (it keeps the id and mount path `admin`, so the
screens live at `/admin/*`) and restart:
@@ -10,7 +10,7 @@ cp -r examples/plugins/admin plugins/admin
docker compose restart web
```
The seeded `admin@plainpages.local` already holds the `admin` role, so the section appears in the
The seeded `admin@plainpages.local` already holds the `admin` permission, so the section appears in the
menu and the screens work immediately.
## What it demonstrates — a *system* plugin
@@ -20,21 +20,21 @@ reference](../scheduling/README.md)). The admin screens instead administer **Pla
stack**, so they use the privileged **`ctx.system`** surface the host exposes to a system plugin:
- **`ctx.system.kratosAdmin`** — create/edit/deactivate/delete Kratos identities (Users).
- **`ctx.system.keto`** — read/write the Keto relationship graph (Groups, Roles).
- **`ctx.system.keto`** — read/write the Keto relationship graph (Groups, Permissions).
- **`ctx.system.hydra`** — register/list/delete Ory Hydra OAuth2 clients.
- **`ctx.system.revoke(sub)`** — the optional instant-revoke hook: a deactivate/delete or a
user's role change kills that subject's live tokens at once instead of waiting out the JWT TTL.
user's permission change kills that subject's live tokens at once instead of waiting out the JWT TTL.
`ctx.system` is populated only when the host wired those services (the dev stack wires Kratos + Keto,
and Hydra when configured). Where a capability is absent the screen degrades to a themed 503 rather
than crashing — see `admin-shared.ts`. Everything else is an ordinary plugin: folder-discovered,
gated per route by `role: "admin"`, rendering the core building blocks in `views/`.
gated per route by `permission: "admin"`, rendering the core building blocks in `views/`.
## Layout
- `plugin.ts` — the manifest: the gated Admin nav fragment, the `admin` role, and the
route table — one thin handler per method+path, all gated by `role: "admin"`.
- `admin-users.ts` · `admin-groups.ts` · `admin-roles.ts` · `admin-clients.ts` — each a set of pure
- `plugin.ts` — the manifest: the gated Admin nav fragment, the `admin` permission, and the
route table — one thin handler per method+path, all gated by `permission: "admin"`.
- `admin-users.ts` · `admin-groups.ts` · `admin-permissions.ts` · `admin-clients.ts` — each a set of pure
view-model builders (unit-tested in the matching `*.test.ts`) plus thin per-route handlers keyed on
`ctx.params` (the host extracts `:id`/`:name`), sharing a small `withX` wrapper that resolves the
admin gate + the needed `ctx.system` clients once.