Rename the coarse gate from role to permission, matching RBAC
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Ory Keto — authorization (ReBAC), the source of truth for roles/groups and the rare
|
||||
# Ory Keto — authorization (ReBAC), the source of truth for permissions/groups and the rare
|
||||
# fine-grained check (README: three tiers of "may I?"). The permission model lives in
|
||||
# namespaces.keto.ts (OPL); DSN comes from the env (the per-service keto DB). The web
|
||||
# app never connects directly — it calls the read (4466) / write (4467) APIs, the ports
|
||||
|
||||
@@ -7,26 +7,27 @@ import { Context, Namespace, SubjectSet } from "@ory/keto-namespace-types"
|
||||
// A Kratos identity. Subjects are written as `identity:<kratos-identity-id>`.
|
||||
class Identity implements Namespace {}
|
||||
|
||||
// A subject set: a named collection of users (and nested groups), resolved transitively.
|
||||
// The admin "Groups" screen manages membership; checks expand it automatically.
|
||||
// A named set of identities (and nested groups), resolved transitively. The admin "Groups"
|
||||
// screen manages membership; checks expand it automatically.
|
||||
class Group implements Namespace {
|
||||
related: {
|
||||
members: (Identity | SubjectSet<Group, "members">)[]
|
||||
}
|
||||
}
|
||||
|
||||
// A coarse role — the source of truth for the JWT `roles` claim. At login the app reads
|
||||
// `Role:<name>#members@identity:<id>` from Keto and projects the result into the token
|
||||
// (README: Login → session JWT). A group can hold a role, so members can be users or groups.
|
||||
class Role implements Namespace {
|
||||
// A coarse permission — an operation a route or menu item gates on, and the source of truth
|
||||
// for the JWT `permissions` claim. At login the app reads `Permission:<name>#granted@identity:<id>`
|
||||
// from Keto and projects the result into the token (README: Login → session JWT). A group can
|
||||
// hold a permission, so grants go to an identity or to a whole group.
|
||||
class Permission implements Namespace {
|
||||
related: {
|
||||
members: (Identity | SubjectSet<Group, "members">)[]
|
||||
granted: (Identity | SubjectSet<Group, "members">)[]
|
||||
}
|
||||
}
|
||||
|
||||
// A fine-grained, relationship-checked resource — README's third "may I?" tier, the rare
|
||||
// live Keto check (e.g. sharing/delegation). Permissions nest: owner ⊇ editor ⊇ viewer.
|
||||
// Grants accept a user directly or any member of a group.
|
||||
// live Keto check (e.g. sharing/delegation). Permits nest: owner ⊇ editor ⊇ viewer.
|
||||
// Grants accept an identity directly or any member of a group.
|
||||
class Resource implements Namespace {
|
||||
related: {
|
||||
owners: (Identity | SubjectSet<Group, "members">)[]
|
||||
|
||||
@@ -41,7 +41,7 @@ selfservice:
|
||||
ui_url: http://localhost:3000/login
|
||||
after:
|
||||
# After authenticating, land on our completion route — it mints the session JWT
|
||||
# (roles from Keto → metadata_public projection → tokenize) and sets our cookie.
|
||||
# (permissions from Keto → metadata_public projection → tokenize) and sets our cookie.
|
||||
default_browser_return_url: http://localhost:3000/auth/complete
|
||||
registration:
|
||||
ui_url: http://localhost:3000/registration
|
||||
@@ -94,7 +94,7 @@ session:
|
||||
same_site: Lax
|
||||
# Session→JWT tokenizer: whoami(tokenize_as: plainpages) mints a short-lived,
|
||||
# locally-verifiable JWT so the hot path never calls Ory. Claims come from the
|
||||
# committed Jsonnet mapper (sub = identity id, email from traits, roles from the
|
||||
# committed Jsonnet mapper (sub = identity id, email from traits, permissions from the
|
||||
# metadata_public projection); signed with tokenizer/jwks.json.
|
||||
whoami:
|
||||
tokenizer:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Session→JWT claims mapper for the `plainpages` tokenizer. Kratos exposes the
|
||||
// session as `session`; `sub` is set from the identity id (subject_source: id) and
|
||||
// can't be overridden here. roles come from metadata_public — the per-login projection
|
||||
// of Keto roles the app refreshes at login (metadata_admin is NOT carried in the session
|
||||
// can't be overridden here. permissions come from metadata_public — the per-login projection
|
||||
// of Keto permissions the app refreshes at login (metadata_admin is NOT carried in the session
|
||||
// the tokenizer sees; metadata_public is). Absent on a fresh identity ⇒ empty list.
|
||||
local session = std.extVar('session');
|
||||
local meta =
|
||||
@@ -12,6 +12,6 @@ local meta =
|
||||
{
|
||||
claims: {
|
||||
email: session.identity.traits.email,
|
||||
roles: if std.objectHas(meta, 'roles') then meta.roles else [],
|
||||
permissions: if std.objectHas(meta, 'permissions') then meta.permissions else [],
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user