Skip to content
ward logoWardSecurity
Zero-dependency authorization decisions with ordered rules, role helpers, ownership predicates, and default deny.
Version
v3.0.0
Size
2.2 KB gzip
Dependencies
Zero dependencies
BrowserNode ≥22SSRDeno
createWardallowdenypredicateANONYMOUS View all 8 exports

Why Ward?

Ward evaluates immutable ordered rules. The first matching rule wins; no match means deny. Typed action, resource, and attribute contracts keep role and ownership policies explicit.

Quick Start

ts
import { allow, createWard, deny, predicate, WILDCARD } from '@vielzeug/ward';

const ward = createWard([
  deny('blocked', WILDCARD, [WILDCARD]),
  allow('editor', 'posts', ['read', 'update'], { when: predicate.owns('authorId') }),
  allow('viewer', 'posts', ['read']),
]);

const decision = ward.decide({
  action: 'update',
  attributes: { authorId: 'u1' },
  principal: { id: 'u1', roles: ['editor'] },
  resource: 'posts',
});
FeatureWardInline conditionals
Ordered first-match policyManual
Default denyManual
Typed actionsPartial
Ownership predicatesManual
Zero dependencies

Features

  • Ordered allow and deny decisions
  • Concise role/action rule factories
  • predicate.owns(), and(), or(), and not()
  • Exact, namespace, and wildcard action/resource patterns
  • Immutable rules, principals, and JSON-compatible attributes
  • Typed batch, bound-principal, and allowed-action checks
  • tap() decision observability
  • Default deny when no rule matches

Installation

sh
pnpm add @vielzeug/ward

Documentation

See Also

  • Postmaster — authorize durable job actions at application boundaries.
  • Refine — consume decisions in accessible UI components.