Skip to main content

ADR 0003: Capability-Based Access Control (CBAC)

Date: 2025-02-20
Status: Accepted

Context

Evalium requires:

  • custom roles (future)
  • granular control for authoring, reporting, scheduling
  • magic link guest access
  • third-party visibility permissions
  • org-level and tenant-level roles

Traditional RBAC (role → static powers) is too rigid.

Decision

Adopt capability-based access control, where:

  • A role is a named bundle of capabilities.
  • Capabilities map 1:1 to actions (e.g., author.question.create).
  • JWT contains role_id only; capabilities are resolved at runtime.
  • Magic link viewers receive temporary capability bundles.

Options Considered

RBAC-only

Cons: inflexible for SMB + enterprise hybrid

Fine-grained permission flags

Cons: messy, hard to manage, not composable

CBAC (chosen)

Pros:

  • Extremely flexible
  • User-defined roles become trivial
  • Perfect for future UI exposing role builder
  • Magic links fit naturally
    Cons:
  • Requires caching capabilities for performance

Consequences

Positive:

  • Scales with feature count
  • Clear auditability
  • No migration pain when roles evolve

Negative:

  • Requires role/capability lookup in runtime
  • Needs caching (Redis) in Tier 2

Notes

Produces a future-proofed foundation matching modern platforms (Linear, Notion).