Generic authorization engine (Gates + Policies) for TypeScript. Inspired by Laravel authorization.
Library only — no roles, permissions, tenants, or URLs from any product are embedded.
npm install @coderic/aclGitHub Packages (org Coderic):
# .npmrc
@coderic:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}npm install @coderic/acl@^0.1.0Repo: https://github.com/Coderic/coderic-acl
| Import | Contents |
|---|---|
@coderic/acl | Registry, gates, policies, claims parsing, AuthPrincipal types |
@coderic/acl/hono | createRequireAuth for Cloudflare Workers / Hono |
@coderic/acl/react | AuthzProvider, RequireAbility |
import{allow,deny,denyAsNotFound,createRegistry,parseClaims,hasAnyRole,hasPermission,}from"@coderic/acl";importtype{AuthPrincipal,ClaimsConfig}from"@coderic/acl";constclaimsConfig: ClaimsConfig={rolesClaim: "https://example.com/roles",permissionsClaim: "https://example.com/permissions",};constregistry=createRegistry().before((user,ability)=>(user?.roles.includes("sudo") ? true : null)).defineGate("billing.read",(user)=>user&&hasPermission(user,"read:billing") ? allow() : deny("Forbidden"),).registerPolicy("invoice",{update(user,invoice){returnuser?.id===invoice.owner_id ? allow() : deny("Not owner");},});registry.authorize(user,"invoice.update",invoice);constprincipal=parseClaims(jwtPayload,claimsConfig);import{createRequireAuth}from"@coderic/acl/hono";constrequireAuth=createRequireAuth({resolveUser: async(c)=>{/* return AuthPrincipal | null */},});app.get("/account",requireAuth,(c)=>c.json(c.get("user")));import{AuthzProvider,RequireAbility}from"@coderic/acl/react";<AuthzProviderregistry={registry}user={principal}><RequireAbilityability="billing.read"><BillingPanel/></RequireAbility></AuthzProvider>Portal repos keep auth/gates.ts and auth/registry.ts at repo root (portal-specific rules). The dashboard imports buildRegistry() from there.
MIT