
Access Control
Access control is one of the most critical aspects of modern application security. While traditional role-based access control (RBAC) has been widely adopted, it often falls short in complex systems where permissions need to be fine-grained and context-aware. This is where Attribute-Based Access Control (ABAC) shines. This project is a custom Shadcn registry which provides system designed to simplify ABAC implementation with strong typing, runtime evaluation, and easy persistence.
Installation
Adding the Access Control library from this registry is straightforward using the Shadcn CLI:
npx shadcn@latest add https://registry.frad-fardeen.workers.dev/r/access-control.json
Key Files
The repository is structured around a few core files:
- src/registry/lib/auth/abac.ts — AccessControl implementation
- src/registry/lib/auth/eval.ts — Condition parsing and evaluation
- src/registry/lib/auth/types/* — Strongly-typed building blocks:
- subject.ts, resource.ts, condition.ts, operator.ts, policy.ts, entitlement.ts
Core Ideas
The design philosophy centers on three principles:
- Types-first: Compile-time guarantees for subjects, actions, and resources using generics.
- Serializable rules: Policies and entitlements are JSON-compatible, making them easy to store in databases or transfer across services.
- Pluggable runtime: Developers can implement custom getConditions functions to load rules from memory, databases, or key-value stores.
Primary Helper Types
Some of the foundational types include:
- BaseSubject — Represents entities like users
({ id: string }). - BaseResource — Defines resources with a
typediscriminator. - Condition — Runtime-evaluable condition AST supporting operators like
equal,notEqual,in. - Policy — A named collection of conditions.
- Entitlement — A serializable descriptor referencing policies or conditions.
How Generics Fit Together
The AccessControl class ties everything together:
AccessControl<S, Actions, ResourceMap>
S: Subject type (extends BaseSubject)
Actions: Tuple of action string literals (e.g., ["read", "edit"])
ResourceMap: Maps resource types to their shapes
Usage Example
Here's a minimal example of defining subjects, resources, and entitlements:
type User = { id: number; name: string; role: "user" | "admin" };
type Doc = { type: "doc"; ownerId: number; published: boolean; editors?: number[] };
type Image = { type: "image"; ownerId: number };
const ACTIONS = ["read", "edit"] as const;
const entitlement = {
id: 123,
resource: "doc",
policies: {
edit: {
requiresResource: true,
conditions: {
kind: "any",
any: [
{ path: "$.subject.id", operator: "equal", value: "$.resource.ownerId" },
{ path: "$.subject.id", operator: "in", value: "$.resource.editors" },
{ path: "$.subject.role", operator: "equal", value: "admin" }
]
}
},
read: {
requiresResource: true,
conditions: {
kind: "all",
all: [
{ path: "$.resource.published", operator: "equal", value: true }
]
}
}
}
};
This entitlement allows:
Document owners, editors, or admins to edit documents.
Users to read documents only if they are published.
Serialization & Persistence
Because conditions, policies, and entitlements are plain JSON objects, they can be stored in:
- Relational databases (JSON columns)
- Key-value stores
- Cloud storage (S3, files)
At runtime, these objects are rehydrated into condition ASTs for evaluation.
Best Practices
-
Keep entitlements minimal and referenceable.
-
Normalize entitlements in databases for efficient querying.
-
Use ResourceMap generics for exhaustive type-checking.
Store conditions as small JSON blobs linked to policies for performance gains.
Alpha Quality Disclaimer
This project is currently alpha-quality software. It may break unexpectedly, and developers are responsible for auditing its security and correctness before using it in production. Think of it as a powerful experimental toolkit rather than a production-ready library.
Appendix: Where to Look in Code
- Condition AST & Operators: condition.ts, operator.ts
- Policy & Entitlement Types: policy.ts, entitlement.ts
- AccessControl Runtime: abac.ts, eval.ts