@nzelajs/authorizer-kengela
v0.1.0
Published
Nzela Authorizer adapter delegating the access decision to Kengela (@kengela/authz-core#isAuthorized), with an org-chart relation resolver.
Maintainers
Readme
@nzelajs/authorizer-kengela
English below - Version francaise plus bas.
The Kengela-backed Authorizer for the Nzela engine. It makes authorization REAL: at its public
entry points the engine hands this adapter an AuthorizationAttempt (who, on which instance, which
action, at the transition or task level) and stays agnostic - it invents NO permission string. THIS
adapter owns the convention that maps the attempt to a Kengela permission (overridable), then
delegates the decision to Kengela (@kengela/authz-core#isAuthorized). Nzela never reimplements the
permission algebra; it only wires the seam.
English
Install
npm add @nzelajs/authorizer-kengelaWhat it provides
KengelaAuthorizer(implementsAuthorizer): onauthorize(repos, attempt)it (1) maps the attempt to a permission string, (2) loads the actor's effective grants via the tenant-scopedrepos.authzstore, (3) resolves the org relation of the actor to the instance, (4) calls Kengela'sisAuthorized(grants, permission, relation, now)and throwsAuthorizationDeniedErrorwhen the decision is deny. Deny-by-default: if norepos.authzstore is wired, it fails closed (relation = "no-authz-store"). Construct it withnew KengelaAuthorizer({ relations, clock?, permissionFor? }).- The attempt -> permission convention is the DEFAULT of this adapter (the engine core is
agnostic and no longer carries it): a case transition maps to
data.case.submit/data.case.withdraw/data.case.dispatch, a task decision todata.approval.visa/data.approval.decide; an app-declaredtransition.permissionornode.permissionwins over the convention. PasspermissionFor: (attempt) => stringto replace it wholesale - so a Kengela user with different permission names plugs their own mapping without touching the core.defaultPermissionForis exported so a custom mapper can fall back to the convention. OrgRelationResolver(implementsRelationResolver): classifies the actor/instance relation asself(actor is requester or beneficiary),unit(same primary org unit),subtree(the subject's unit is in the actor unit's subtree) ortenant(same tenant, nothing narrower provable). It readsrepos.organd returnstenantwhenever a narrower relation cannot be proven (fail-closed). The result is passed through Kengela'stenantScopedRelationfor cross-tenant isolation (defense-in-depth): a resource outside the actor's tenant collapses tonone, which only aglobalgrant can cover.
The decision is Kengela's. The scope order (own subset unit subset subtree subset tenant
subset global) lives in @kengela/authz-core; the permission NAMES (e.g. data.case.dispatch) are
this adapter's default convention, not the engine's; this package is the wiring that maps the attempt
and feeds Kengela grants and a relation.
Francais
Installation
npm add @nzelajs/authorizer-kengelaCe que ca fournit
KengelaAuthorizer(implementeAuthorizer) : surauthorize(repos, attempt), il (1) mappe la tentative vers une chaine de permission, (2) charge les droits effectifs de l'acteur via le store tenant-scoperepos.authz, (3) resout la relation org de l'acteur a l'instance, (4) appelleisAuthorized(grants, permission, relation, now)de Kengela et leveAuthorizationDeniedErrorquand la decision est un refus. Deny-by-default : sans storerepos.authz, il echoue ferme (relation = "no-authz-store"). Construction :new KengelaAuthorizer({ relations, clock?, permissionFor? }).- La convention tentative -> permission est le DEFAUT de cet adapter (le coeur du moteur est
agnostique et ne la porte plus) : une transition de dossier mappe vers
data.case.submit/data.case.withdraw/data.case.dispatch, une decision de tache versdata.approval.visa/data.approval.decide; untransition.permissionounode.permissiondeclare par l'app prime sur la convention. FournirpermissionFor: (attempt) => stringpour la remplacer entierement - ainsi un utilisateur de Kengela avec d'autres noms de permission branche sa correspondance sans toucher au coeur.defaultPermissionForest exporte pour qu'un mappeur personnalise puisse retomber sur la convention. OrgRelationResolver(implementeRelationResolver) : classe la relation acteur/instance enself(l'acteur est le demandeur ou le beneficiaire),unit(meme unite primaire),subtree(l'unite du sujet est dans le sous-arbre de l'unite de l'acteur) outenant(meme tenant, rien de plus etroit prouvable). Il litrepos.orget renvoietenantdes qu'une relation plus etroite n'est pas prouvable (fail-closed). Le resultat passe partenantScopedRelationde Kengela pour l'isolation cross-tenant (defense en profondeur) : une ressource hors du tenant de l'acteur s'effondre ennone, que seul un droitglobalpeut couvrir.
La decision appartient a Kengela. L'ordre des portees (own subset unit subset subtree subset
tenant subset global) vit dans @kengela/authz-core ; les NOMS de permission (ex.
data.case.dispatch) sont la convention par defaut de cet adapter, pas celle du moteur ; ce paquet
n'est que le cablage qui mappe la tentative et fournit a Kengela droits et relation.
License
Apache-2.0
