Skip to content

The last authorization library you'll need.

Define policies once, get database filters, UI guards, and API protection automatically — for both JavaScript and TypeScript.

policy.ts
// Define policies once
const policy = definePolicy({
  rules: [{
    action: 'post.edit',
    effect: 'allow',
    when: ({ subject, resource }) =>
      subject.id === resource.authorId
  }]
})

// Use everywhere
const canEdit = policy.check(
  'post.edit',
  { subject: user, resource: post }
)

const decision = policy.checkDetailed(
  'post.edit',
  { subject: user, resource: post }
)

Key Features

🛡️

Security by Construction

Eliminate entire classes of authorization bugs through compile-time validation and automated tenant isolation.

Zero Boilerplate

Write policies once, get type-safe API guards, database filters, and UI components automatically.

🔧

Works with Your Stack

Drop-in support for Prisma, Next.js, React, Express, and any TypeScript application.

🚀

Production Ready

Battle-tested in high-scale applications with sub-millisecond overhead and comprehensive error handling.

👥

Team-Friendly

Clear error messages, visual policy debugging, and documentation that makes security approachable.

🔄

Multi-Tenant Safe

Automatic tenant isolation prevents cross-tenant data leaks without manual validation code.

The Problem

Traditional authorization approaches scatter security logic across your codebase:

typescript
// Scattered checks everywhere - easy to forget or get wrong
if (user.role !== 'admin' && user.tenantId !== post.tenantId) {
  throw new Error('Access denied')
}

if (!canUserEditPost(user, post)) {
  throw new Error('Cannot edit')
}

// Repeated in 100+ places across your app...

Result

Authorization bugs in production, security vulnerabilities, and frustrated developers.

The AuthzKit Solution

Define policies once, enforce everywhere automatically:

typescript
// Define once - centralized and type-safe
const policy = definePolicy({
  byAction: {
    'post.edit': [{
      effect: 'allow',
      when: ({ subject, resource }) =>
        subject.id === resource.authorId || subject.role === 'admin'
    }]
  }
})

// Use everywhere - automatic enforcement
const decision = policy.checkDetailed('post.edit', { subject: user, resource: post })

// Use decision results for authorization
if (!decision.allow) {
  throw new Error(decision.reason || 'Access denied')
}

// Apply field masking using readMask
const posts = await prisma.post.findMany({
  // Apply any filtering based on decision attributes
  where: decision.attrs || {}
})

Result

Security bugs become impossible, not just unlikely.

Why AuthzKit?

Before AuthzKit: Security Chaos
  • ❌ Authorization scattered across 100+ files
  • ❌ Easy to forget checks in new features
  • ❌ Manual tenant validation everywhere
  • ❌ Security bugs discovered in production
  • ❌ Slow, error-prone development
After AuthzKit: Security by Design
  • ✅ All authorization in centralized policies
  • ✅ Compile-time errors prevent security bugs
  • ✅ Automatic tenant isolation
  • ✅ Security violations impossible by construction
  • ✅ Fast, confident development