npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

better-auth-abac

v1.3.1

Published

A package for ABAC in better-auth

Readme

IN BETA - IN DEVELOPMENT

better-auth-abac

A flexible and extensible Attribute-Based Access Control (ABAC) plugin for the Better Auth framework. This package allows developers to implement fine-grained authorization using attributes, policies, and rules with comprehensive access control validation.

Features

  • Attribute-Based Access Control: Define and manage user, role, resource, action, and environment attributes
  • Policy Management: Create flexible policy sets with priority-based evaluation
  • Dynamic Attributes: Support for computed attributes with caching
  • Resource Management: Comprehensive resource type and instance management
  • Access Logging: Built-in access request tracking and audit trails
  • Multiple Authorization Patterns: Support for read, write, delete, and custom action permissions
  • Extensible Schema: Flexible attribute system supporting various data types and categories

Installation

npm install better-auth-abac

Setup

import { betterAuth } from "better-auth"
import { abac, createAbacAdapter } from "better-auth-abac"

// Initialize your database adapter
const abacAdapter = await createAbacAdapter({
    type: "mysql" // mysql | postgres | sqlite
    uri: process.env.DB_URL!
    // filename: "./db" // OPTIONAL FOR SQLITE
})

export const auth = betterAuth({
    // other options here
    plugins: [abac(abacAdapter)]
})

Alternative Setup with Options

const abacAdapter = await createAbacAdapter({
    type: "mysql" // mysql | postgres | sqlite
    uri: process.env.DB_URL!
    // filename: "./db" // OPTIONAL FOR SQLITE
})

const OPTIONS = {
	database: drizzleAdapter(main_db, {
		provider: "mysql",
		schema: {
			...schema,
		},
	}),
	emailAndPassword: {
		enabled: true,
	},
    plugins: [abac(abacAdapter)]
} satisfies BetterAuthOptions;

export const auth = betterAuth({
    ...OPTIONS,
    appName: "My App"
})

Database Schema

⚠️ IMPORTANT: Please remember to run npx @better-auth/cli generate and push changes to your database before using this plugin.

The plugin automatically creates the following tables in your database:

  • role: User roles with attributes
  • attribute: Attribute definitions with types and categories
  • user_attribute: User-specific attribute assignments
  • role_attribute: Role-based attribute assignments
  • resource_type: Definitions for different resource types
  • resource: Resource instances with ownership
  • resource_attribute: Resource-specific attributes
  • actions: Available actions per resource type
  • action_attribute: Action-specific attributes
  • environment_attribute: Context-based attributes
  • policy_set: Policy groupings with priorities
  • policy: Individual policies with rules
  • policy_rule: Detailed policy rule definitions
  • policy_target: Policy targeting specifications
  • access_request: Access request audit logs
  • dynamic_attribute: Computed attributes with caching

Usage

Client-Side API

Check User Action Permissions

// Check if user can perform a specific action
const result = await authClient.abac.canuserperformaction({
	subjectId: "user123",
	resourceId: "document456", // optional
	resourceType: "document", // optional
	actionName: "edit",
	context: {
		ip_address: "192.168.1.1",
		time_of_day: "business_hours",
		department: "engineering",
	},
});

console.log(result);

// EXAMPLE RETURN

{
    "decision": {
        "decision": "not_applicable", // not_applicable, permit, deny
        "reason": "No applicable policies found", // reason for permit / deny / not_applic
        "appliedPolicies": [], // applied policies to the decision
        "processingTimeMs": 292
    }
}

Check Read Permissions

const canRead = await authClient.abac.canuserread({
	userId: "user123",
	resourceId: "document456",
	context: {
		classification_level: "internal",
	},
});

console.log(canRead);

Check Write Permissions

const canWrite = await authClient.abac.canuserwrite({
	userId: "user123",
	resourceId: "document456",
	context: {
		modification_reason: "content_update",
	},
});

console.log(canWrite);

Check Delete Permissions

const canDelete = await authClient.abac.canuserdelete({
	userId: "user123",
	resourceId: "document456",
	context: {
		backup_exists: "true",
	},
});

console.log(canDelete);

Bulk Resource Permission Check

// Check permissions across multiple resources
const bulkResult = await authClient.abac.canuserperformactiononresources({
	userId: "user123",
	actionName: "view",
	resourceIds: ["doc1", "doc2", "doc3"],
	context: {
		request_purpose: "audit",
	},
});

console.log(bulkResult);

Test Plugin Connection

const testResult = await authClient.abac.test();
console.log(testResult.message); // "ABAC plugin is working!"

Server-Side Integration

The plugin automatically handles user registration by:

  1. Creating a default "USER" role if it doesn't exist
  2. Assigning new users to the default role
  3. Creating user resources for access control

Policy Configuration

Policies are stored as JSON structures in the database and support:

  • Attribute Matching: Compare user, resource, action, and environment attributes
  • Logical Operators: AND, OR conditions between rules
  • Comparison Operators: equals, not_equals, greater_than, less_than, contains, etc.
  • Priority Handling: Higher priority policies override lower priority ones
  • Effect Types: Allow or Deny decisions

Dynamic Attributes

Support for computed attributes that are:

  • Calculated at runtime based on rules
  • Cached for performance (configurable timeout)
  • Context-aware and environment-sensitive

Environment Context

The plugin supports rich contextual information including:

  • IP addresses and geographic location
  • Time-based access (business hours, weekends)
  • Device and browser information
  • Custom application context

API Endpoints

All endpoints are automatically mounted under /api/auth/abac/:

  • POST /api/auth/abac/canuserperformaction - Generic action permission check
  • POST /api/auth/abac/canuserread - Read permission check
  • POST /api/auth/abac/canuserwrite - Write permission check
  • POST /api/auth/abac/canuserdelete - Delete permission check
  • POST /api/auth/abac/canuserperformactiononresources - Bulk permission check
  • GET /api/auth/abac/test - Plugin health check

Example Use Cases

Document Management System

// Check if user can edit a document based on:
// - User's role and department
// - Document classification level
// - Current time (business hours only)
// - User's previous edit history

const canEdit = await authClient.abac.canuserperformaction({
	subjectId: userId,
	resourceId: documentId,
	resourceType: "document",
	actionName: "edit",
	context: {
		current_time: new Date().toISOString(),
		user_department: "legal",
		document_classification: "confidential",
		recent_edit_count: "2",
	},
});

Multi-tenant SaaS Application

// Ensure users can only access resources in their tenant
const canAccess = await authClient.abac.canuserperformactiononresources({
	userId: userId,
	actionName: "view",
	resourceIds: requestedResourceIds,
	context: {
		tenant_id: userTenantId,
		subscription_level: "premium",
		feature_flags: JSON.stringify(enabledFeatures),
	},
});

Contributing

Contributions are welcome! Please ensure your code follows the established patterns and includes appropriate tests.

License

MIT License