Permit
⚡ Quick Reference
Package: @vielzeug/permit · Category: Auth
Key exports: createPermit, owns
When to use: Minimal RBAC engine with deterministic precedence, wildcard rules, dynamic predicates, and audit logging.
@vielzeug/permit is a small authorization engine for role/resource/action checks.
Installation
sh
pnpm add @vielzeug/permitsh
npm install @vielzeug/permitsh
yarn add @vielzeug/permitQuick Start
ts
import { ANONYMOUS, WILDCARD, createPermit, owns } from '@vielzeug/permit';
const permit = createPermit<'read' | 'update', { authorId: string }>([
{ role: 'editor', resource: 'posts', action: 'read', effect: 'allow' },
{
role: 'editor',
resource: 'posts',
action: 'update',
effect: 'allow',
when: owns('authorId'),
},
{ role: 'blocked', resource: 'posts', action: WILDCARD, effect: 'deny', priority: 100 },
{ role: ANONYMOUS, resource: 'posts', action: 'read', effect: 'allow' },
]);
permit.can({ id: 'u1', roles: ['editor'] }, 'posts', 'read');
permit.can({ id: 'u1', roles: ['editor'] }, 'posts', 'update', { authorId: 'u1' });
const bound = permit.forUser({ id: 'u1', roles: ['editor'] });
bound.canAll('posts', ['read', 'update'], { authorId: 'u1' });
bound.explain('posts', 'update', { authorId: 'u2' });
bound.checkAll([
{ resource: 'posts', action: 'read' },
{ resource: 'posts', action: 'update', data: { authorId: 'u1' } },
]);
bound.rulesInScope('posts');Why Permit?
- Minimal API:
can,canAll,canAny,checkAll,allowedActions,explain,rulesInScope,forUser - Deterministic precedence model
- Deny-overrides at top precedence
- Runtime predicates directly on rules
- Exact matching with explicit wildcards
- Zero dependencies
| Feature | Permit | CASL | AccessControl |
|---|---|---|---|
| Bundle size | 0.1 KB | ~11 kB | ~7 kB |
| Typed rule contracts | ✅ | Partial | Partial |
| Deterministic deny precedence | ✅ | ✅ | ✅ |
| Rule predicates with request data | ✅ | ✅ | ⚠️ (manual patterns) |
| Wildcard action support | ✅ | ✅ | ✅ |
| Principal-bound API | ✅ (forUser) | Partial | ❌ |
| Explainable decisions | ✅ | Partial | ❌ |
| Zero dependencies | ✅ | ❌ | ❌ |
Use Permit when you want predictable authorization decisions with typed rules and explicit introspection APIs.
Consider larger policy frameworks when you need ecosystem-specific integrations or policy storage outside application code.
Features
- One rule primitive:
PermitRulepassed tocreatePermit(rules) - Decision methods:
permit.can,permit.canAll,permit.canAny,permit.explain - Batch decisions:
permit.checkAll(principal, checks) - Rule introspection:
permit.rulesInScope(principal, resource, data?) - Action enumeration:
permit.allowedActions(principal, resource, data?, knownActions?) - Explicit wildcard support with
WILDCARD - Anonymous checks via
nullprincipal plusANONYMOUSrole rules - Ownership helper via
owns(attributeKey) - Principal-bound API via
permit.forUser(principal)
Compatibility
| Environment | Support |
|---|---|
| Browser | ✅ |
| Node.js | ✅ |
| SSR | ✅ |
| Deno | ✅ |