@vielzeug/permit
v2.1.0
Published
> Minimal, deterministic authorization engine.
Readme
@vielzeug/permit
Minimal, deterministic authorization engine.
@vielzeug/permit is a small policy engine built around one rule primitive and one decision function.
Installation
pnpm add @vielzeug/permit
# npm install @vielzeug/permit
# yarn add @vielzeug/permitQuick Start
import { ANONYMOUS, WILDCARD, createPermit } from '@vielzeug/permit';
const permit = createPermit({
predicates: {
isOwner: ({ principal, data }) => principal.id === data?.authorId,
},
});
permit
.set({ role: 'editor', resource: 'posts', action: 'read', effect: 'allow' })
.set({ role: 'editor', resource: 'posts', action: 'update', effect: 'allow', when: 'isOwner' })
.set({ role: 'blocked', resource: 'posts', action: WILDCARD, effect: 'deny', priority: 100 })
.set({ role: ANONYMOUS, resource: 'posts', action: 'read', effect: 'allow' })
.set({ role: WILDCARD, resource: 'status', action: 'read', effect: 'allow' });
const principal = { id: 'u1', roles: ['editor'] };
permit.can(principal, 'posts', 'read');
permit.can(principal, 'posts', 'update', { authorId: 'u1' });
permit.withUser(principal).can('status', 'read');API
createPermit<TAction, TData>(options?)permit.set(rule)permit.can(principal, resource, action, data?)permit.withUser(principal).can(resource, action, data?)permit.clear()permit.exportPolicy()permit.importPolicy(policy)
Decision Rules
- Default outcome is deny.
- Higher
prioritywins. - For equal priority, more specific rules win over wildcard rules.
- If top-precedence rules conflict,
denyoverridesallow. - Result does not depend on role order in the principal payload.
Notes
- Role/resource/action values are normalized (trim + lowercase).
- Predicates are referenced by id (
when) and resolved through thepredicatesoption. - Exported policy is JSON-serializable.
- Invalid principal payloads throw instead of silently falling back to anonymous.
License
MIT © Helmuth Saatkamp — part of the Vielzeug monorepo.
