Skip to main content

policies overview

When and why to use ABAC policies — time, IP, attribute, and dynamic deny rules that go beyond what RBAC roles can express.

When to Use Policies

Roles cover the common case: "editors can update posts." Some requirements need more than roles can express:

Loading diagram...

  • Time-based restrictions — deny writes on weekends or outside business hours
  • IP/geo-fencing — allow access only from trusted networks
  • Cross-attribute checks — allow updates only when subject and resource share a department
  • Dynamic deny rules — block specific users or flag suspicious behavior without changing role assignments
  • Maintenance mode — deny all writes globally when a feature flag is on

ABAC policies share the role evaluation pipeline. The engine AND-combines policies — a deny from any policy is final.


Reading order

Each topic has its own page:

PageCovers
building policiespolicy() builder, defineRule(), wildcards, hierarchical resources
rulesRule structure, effect, priority, scopes, metadata
conditionsThe When builder — operators, semantic shortcuts, field paths
$-variable referencesCompare two fields on the same request via $subject.id etc.
nesting and/or/notCompose AND/OR/NOT groups, whenAny(), depth limit
policy targetsPre-filter policies by action, resource, or role
combining algorithmsdeny-overrides, allow-overrides, first-match, highest-priority
layered exampleFull RBAC + ABAC example, evaluation walkthrough

Quick example

import { policy } from '@gentleduck/iam'
 
const weekendDeny = policy('deny-weekends')
  .name('Deny on Weekends')
  .desc('Block all write operations on weekends')
  .version(1)
  .algorithm('deny-overrides')
  .rule('r-deny-weekends', (r) =>
    r
      .deny()
      .on('create', 'update', 'delete')
      .of('*')
      .when((w) => w.env('dayOfWeek', 'in', [0, 6])),
  )
  .build()
import { policy } from '@gentleduck/iam'
 
const weekendDeny = policy('deny-weekends')
  .name('Deny on Weekends')
  .desc('Block all write operations on weekends')
  .version(1)
  .algorithm('deny-overrides')
  .rule('r-deny-weekends', (r) =>
    r
      .deny()
      .on('create', 'update', 'delete')
      .of('*')
      .when((w) => w.env('dayOfWeek', 'in', [0, 6])),
  )
  .build()

This policy:

  • Has algorithm deny-overrides (any deny rule that matches → policy returns deny)
  • Targets writes only (not reads)
  • Uses env('dayOfWeek', 'in', [0, 6]) — Sunday or Saturday → deny

FAQ