@kindgi/authz
npm install @kindgi/authz · source
Public authorization shape for Kindgi™: the vocabulary and interfaces that callers, policy enforcement points (PEPs) and policy executors share. Object types, actions and relation names follow an OpenFGA-style model; the FGA store and the check implementation are supplied by the deployment. @kindgi/api uses these types in its middleware and bindings.
Purpose
Section titled “Purpose”Give every enforcement site one vocabulary — which object types exist, which actions apply to each, how an action maps to an FGA relation, who the caller is — so a check means the same thing in every layer. The package is types and pure functions only; it holds no runtime state.
Exports
Section titled “Exports”- Vocabulary —
OBJECT_TYPES/ObjectType,ACTIONS/Action,ACTION_TO_RELATION(e.g.read→can_read),OBJECT_ACTIONS(the actions meaningful per object type, so a PEP can rejectrotateon an agent before calling FGA),ResourceRef,resourceKey(ref),ref(type, id). - Principals —
Principal(actor, optionalonBehalfOf, optionalscope),PrincipalRef,PrincipalKind(user,agent,service_account,system),DownscopedPermissions(allowedActions/deniedActions).userPrincipal,systemPrincipal,serviceAccountPrincipal,delegate(actor, onBehalfOf, scope?)(throws on cross-tenant delegation),downscope(principal, scope).fgaSubject(ref)— the FGA subject string for a principal;systemmaps touser:system.
- PEP helpers —
principalFromToken(token)(auserIdgives a user principal, else atokenIdgives a service-account principal, else it throws),TokenLike,denyPayload(action, type, id, reason)/DenyPayload(the structured 403 body,code: 'permission-denied'). - Decisions —
AuthzCheckBindingwithcheck(principal, action, resource, ctx?)andcheckBatch(...),AuthzCheckContext(correlationId,runId), andDecision(allowed,reason,failing,evidence). The effective permission is the intersection of actor,onBehalfOfandscope. - Tuples —
TupleIntentandTupleEnqueueHook(the hook every content and config binding calls inside its write transaction).tuplesForCreate(entity, creatorUserId?)/tuplesForDelete(entity)overEntityRef;tuplesForDeleteremoves only the parent / scope tuple.- Subject and object helpers (
userSubject,teamMemberSubject,tenantObject…runObject,scopeSubject) and the tuple-sideScope. - Membership and grants:
teamMembershipTuple,projectMembershipTuple,teamProjectGrantTuple(TeamRole,ProjectRole),machineAccessTupleforagent/service_accountsubjects (MachineSubject,AgentAccessResource), and its agent shorthandagentAccessTuple.
- Reviewer roles —
ReviewerRole(standard,senior,admin) andREVIEWER_ROLE_RANK, where a higher rank covers the lower ones.
Example
Section titled “Example”import { type AuthzCheckBinding, type TupleEnqueueHook, denyPayload, principalFromToken, ref, tuplesForCreate,} from '@kindgi/authz';import type { ProjectId, TenantId, UserId } from '@kindgi/types';
const tenantId = 'acme' as TenantId;const creator = 'user-1' as UserId;const principal = principalFromToken({ tenantId, userId: creator });
// A project binding calls this inside its write transaction with the new row id:// a `parent` tuple (tenant:acme → project) plus an `owner` tuple for the creator.const enqueueTuples: TupleEnqueueHook = (rowId) => tuplesForCreate({ kind: 'project', id: rowId as ProjectId, tenantId }, creator);
// At a PEP: ask the decision point, and turn a deny into the structured 403 body.async function authorizeDelete(authz: AuthzCheckBinding, projectId: string) { const decision = await authz.check(principal, 'delete', ref('project', projectId), { correlationId: 'req-42', }); return decision.allowed ? undefined : denyPayload('delete', 'project', projectId, decision.reason);}Non-goals
Section titled “Non-goals”- The check implementation and the FGA store.
AuthzCheckBindingis an interface; the authorization model, the store and the worker that applies queued tuples are supplied by the deployment. - HTTP middleware.
principalFromTokenanddenyPayloadare framework-neutral; the Hono middleware lives in@kindgi/api. - Cross-tenant delegation.
delegatethrows when the actor andonBehalfOfbelong to different tenants.
Related
Section titled “Related”@kindgi/api— the middleware,TokenResolution, and the bindings that callTupleEnqueueHook.@kindgi/types— the branded ids used inEntityRefandPrincipalRef.
License
Section titled “License”Apache License 2.0 — see LICENSE.