granter

Introduction

Composable, type-safe authorization for TypeScript

granter

Composable, type-safe authorization for TypeScript

Authorization, not Authentication

granter is an authorization library (authz), not authentication (authn). It assumes you already have an authenticated user and helps you define what they can do.

Why granter?

  • ✨ Composable - Build complex permissions from simple rules
  • 🔒 Type-safe - Full TypeScript inference with generic contexts
  • ⚡ Async-first - Works seamlessly with databases, APIs, and DataLoader
  • 🔧 Framework-agnostic - Works with Express, Hono, Next.js, GraphQL, and more
  • đŸĒļ Zero dependencies - Lightweight and performant

Quick Example

import { permission, or } from 'granter';

// Define your context
type AppContext = {
  user: { id: string; role: string };
  db: Database;
};

// Create permissions
const isAdmin = permission('isAdmin', (ctx: AppContext) => ctx.user.role === 'admin');

const isPostOwner = permission(
  'isPostOwner',
  async (ctx: AppContext, post: Post) => post.authorId === ctx.user.id
);

// Compose permissions
const canEditPost = or(isPostOwner, isAdmin);

// Use them
const ctx: AppContext = { user: { id: '1', role: 'user' }, db };
const post = await db.getPost('123');

// Check permission
if (await canEditPost(ctx, post)) {
  await db.updatePost(post);
}

// Require permission (throws if denied)
await canEditPost.orThrow(ctx, post);

// Filter array of resources
const editablePosts = await canEditPost.filter(ctx, allPosts);

// Debug why permission was denied
const explanation = await canEditPost.explain(ctx, post);
console.log(explanation);

Installation

npm install granter

How it Works

graph LR
    A[Auth Library] --> B[Create Context]
    B --> C[granter]
    C --> D[Your App]
    A -.->|"Who are you?"| B
    C -.->|"What can you do?"| D
  1. Authentication (external) - Verify user identity with any auth library
  2. Create Context - Build your app context with user info, database, etc.
  3. Authorization (granter) - Check permissions based on context
  4. Execute - Run your application logic

Next Steps