← All work
Technical writeup

author.js

Type-safe authorization framework

ActiveTypeScriptAuthorizationRBAC / ABAC / ReBACSource ↗

Overview

Authorization logic is where clean codebases go to die. Checks get scattered across route handlers, duplicated between the API layer and the database layer, and drift silently as products evolve. author.js pulls that logic into one typed, testable policy layer.

It supports the three models real systems actually need — role-based (RBAC), attribute-based (ABAC), and relationship-based (ReBAC) — and lets them compose, because production authorization is never just one of them.

Design

The core primitive is a policy: a pure, typed function from (subject, action, resource, context) to a decision. Policies are declared once and the framework derives everything else:

const policy = definePolicy({
  document: {
    read: allowIf(
      role("admin"),
      relation("viewer"),
      attribute((doc, user) => doc.orgId === user.orgId && !doc.archived),
    ),
    delete: allowIf(role("admin"), relation("owner")),
  },
});
  • End-to-end inference. Subjects, actions, and resources are inferred from the policy definition. can(user, "delete", doc) fails at compile time if the action doesn't exist for that resource type — authorization typos become type errors.
  • Backend enforcement. Decisions aren't just booleans. Policies compile to filter predicates so list endpoints can push authorization into the query (WHERE clauses) instead of fetching and discarding rows.
  • Decision tracing. Every denial carries the exact rule chain that produced it, which turns "why can't this user see this?" from an afternoon of debugging into a log line.

Key decisions

Policies as data, not middleware. Keeping policies framework-agnostic means the same definitions run in HTTP handlers, background jobs, and tests. Middleware adapters are thin wrappers on top.

Deny-by-default with explicit escape hatches. Every action not explicitly allowed is denied, and overrides are loud, greppable constructs rather than config flags.

Status

Actively developed. Core RBAC/ABAC/ReBAC engine, type inference, and enforcement adapters are in place; query-filter compilation is expanding to more ORMs.