Align the authorization vocabulary: User, Group, Permission #43
Reference in New Issue
Block a user
Delete Branch "role-vocabulary"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Aligns the authorization vocabulary and documents the model. Supersedes #40, whose commits are included here.
The model is now
Identity → Group → Permission.Identity(was ourUser) matches Kratos, which owns that record. Keto subjects areidentity:<kratos-id>. It collided with theIdentityDTO#plugin-apire-exports fromkratos-admin.ts— that one is the full Kratos record and keeps the plain name; ours is the JWT projection, nowSessionIdentity, reached asctx.identity.Permission(wasRole) follows RBAC: a permission is one operation ("read shifts"), a role is a bundle of them. A route gates on one operation, so it gates on a permission; a bundle is just a group with several grants, and groups nest. There is noRolenamespace. The Keto relation isgranted(Permission:x#granted@identity:y); Group keepsmembers.Groupunchanged.Resourceunchanged — the separate per-row tier, and the only place Ory's own sense of "permission" (permits: view/edit/delete) applies.Manifest surface:
route.permission,navNode.permission,permissions: [{ name, description }],PermissionDecl. JWT claim andctxfield arepermissions.HOST_API_VERSIONstays 1.0.0 — unreleased, no plugin authors to break. No data migration:keto-migrateruns Keto's own bundled schema migrations and our tuples are runtime data, sodocker compose down -vcovers it.UI labels stay in ordinary words — the admin menu says "Users", not "Identities", per Nielsen's heuristic #2. Not a rename of an Ory concept: Ory's docs state it uses "identity" interchangeably with "users"/"accounts". Same split as
chrome.user/ShellUser(avatar view-model) vsSessionIdentity(entity). Recorded in AGENTS.md so it is not re-litigated.README gains
## Identities, groups & permissionsbefore Building plugins, since a manifest'spermission:gate is unreadable without the model: entity table, a worked graph over three people, a per-route can/cannot walkthrough, the trap that a per-rowResourcegrant never widens a coarse gate, and the point that Keto ships no namespaces at all — all four are ours.The Security model section is cut 70 → 36 lines. Its threat table restated code readable at its source (alg allowlist,
frame-ancestors,nosniff,localPath,ORY_TIMEOUT_SEC) or duplicated the config table. What remains is only what a deployment gets wrong without it: the private network as the sole guard on the Ory APIs, signed-not-encrypted claims, the 30-day Kratos session behind the ~10m JWT, and non-instant offboarding. The CSRF opt-in footgun moved next toctx.verifyCsrf.Rename the plugin permission gate to role and document the modelto Align the authorization vocabulary with Ory: permission→role, User→IdentityAlign the authorization vocabulary with Ory: permission→role, User→Identityto Align the authorization vocabulary: Identity, Group, PermissionAlign the authorization vocabulary: Identity, Group, Permissionto Align the authorization vocabulary: User, Group, Permissione66c530b0atoc30cd95ebd