entitlement-lite
v0.1.0
Published
Tiny RBAC/ABAC permission engine for TypeScript — role-based access with rule-lite-powered attribute conditions.
Maintainers
Readme
entitlement-lite
Tiny, dependency-light RBAC (role-based access control) engine for TypeScript, with an ABAC (attribute-based) escape hatch powered by rule-lite.
Define roles, attach permissions, optionally gate a permission behind a condition evaluated against runtime context — and ask a single question: can(subject, action, resource).
Install
npm install entitlement-liteQuick start
import { EntitlementEngine } from 'entitlement-lite';
const engine = new EntitlementEngine([
{
name: 'admin',
permissions: [{ action: '*', resource: '*' }],
},
{
name: 'editor',
permissions: [
{ action: 'view', resource: 'invoice' },
{ action: 'edit', resource: 'invoice' },
],
},
]);
engine.can({ roles: ['editor'] }, 'edit', 'invoice'); // true
engine.can({ roles: ['editor'] }, 'delete', 'invoice'); // falseAttribute-based conditions (ABAC)
Permissions can carry an optional condition — a rule-lite Rule evaluated against merged context ({ subject, resource, ...context }):
const engine = new EntitlementEngine([
{
name: 'approver',
permissions: [
{
action: 'approve',
resource: 'invoice',
condition: { all: [{ field: 'amount', operator: 'lte', value: 5000 }] },
},
],
},
]);
engine.can({ roles: ['approver'] }, 'approve', 'invoice', { amount: 4000 }); // true
engine.can({ roles: ['approver'] }, 'approve', 'invoice', { amount: 9000 }); // falseAPI
| Export | Signature | Description |
|---|---|---|
| EntitlementEngine | new EntitlementEngine(roles?: Role[]) | Stateful engine; .can() and .registerRole() |
| EntitlementEngine#can | (subject, action, resource, context?) => boolean | True if any matching permission grants access |
| EntitlementEngine#registerRole | (role: Role) => void | Add or overwrite a role after construction |
| can | (roles, subject, action, resource, context?) => boolean | Stateless one-off check |
action and resource support the wildcard '*' on either side of a Permission.
Angular example
@Injectable({ providedIn: 'root' })
export class EntitlementService {
private engine = new EntitlementEngine(this.roleConfig.roles);
canEdit(resource: string): boolean {
return this.engine.can(this.currentUser, 'edit', resource);
}
}Use canEdit() behind a structural directive (*ngIf) or a route guard to keep permission logic out of components.
Why a separate package instead of one bigger "auth-lite"?
See CASE_STUDY.md for the RBAC-vs-ABAC design rationale, why this depends on rule-lite rather than reimplementing condition evaluation, and trade-offs against heavier options like OPA or Casbin.
License
MIT
