Skip to content
CIVersionSizeTypeScriptDependencies
Permit logo

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.

Related: Logit · Routeit · Wireit

@vielzeug/permit is a small authorization engine for role/resource/action checks.

Installation

sh
pnpm add @vielzeug/permit
sh
npm install @vielzeug/permit
sh
yarn add @vielzeug/permit

Quick 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
FeaturePermitCASLAccessControl
Bundle size0.1 KB~11 kB~7 kB
Typed rule contractsPartialPartial
Deterministic deny precedence
Rule predicates with request data⚠️ (manual patterns)
Wildcard action support
Principal-bound API✅ (forUser)Partial
Explainable decisionsPartial
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: PermitRule passed to createPermit(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 null principal plus ANONYMOUS role rules
  • Ownership helper via owns(attributeKey)
  • Principal-bound API via permit.forUser(principal)

Compatibility

EnvironmentSupport
Browser
Node.js
SSR
Deno

Documentation

See Also

  • Routeit for route-level authorization middleware.
  • Logit for structured audit logs of permission checks.
  • Eventit for event-driven permission workflows.