docs: record module authorization architecture

Adds ADR 0014 recording the durable architecture Phase 5A established
across both passes: the shared contracts-layer PermissionDeclaration,
manifest version 3 replacing version 2's bare permission strings, the
reserved core.* namespace and the structural guarantee that a
module-vs-Core collision always surfaces as
ModulePermissionCompositionError rather than the generic
PermissionRegistryError duplicate path, deterministic registry
composition, startup ordering, repository-root/package-version
resolution, registry injection into apps/api's enforcement and
explicit-grant HTTP API, the static-snapshot/historical-record
preservation guarantees, and Doctor/modules:validate integration.
Indexes it in the ADR README, cross-references it from ADR 0006 (only
its manifestVersion 2 / permission-string decision is superseded; the
rest of ADR 0006 remains accepted, and its historical text is left
untouched) and ADR 0013 (module permission registration, deferred
there, is what ADR 0014 implements), and links it from the relevant
development documentation.

Corrects two comments discovered during a direct source audit that
overstated where a module-vs-Core permission collision is actually
caught (core/src/modules/permissions.ts,
apps/api/src/platform-permissions.ts) — comment-only, no behavior
change, already covered by existing tests. Also corrects a
documentation claim in docs/development/authorization.md that
incorrectly implied removing a module blocks explicit revocation of
its historical grants; grants-routes.ts's revoke handler never
consults the permission registry, so revocation remains unaffected.
This commit is contained in:
ekklesia
2026-07-24 17:49:42 -05:00
parent edd7148aa8
commit 9fa051be61
8 changed files with 329 additions and 52 deletions
+17 -13
View File
@@ -6,9 +6,9 @@ surfaces.
## Current status
Phase 3 is complete; Phase 4A (Core identity foundation), Phase 4B (identity HTTP transport), and
Phase 4C (Core authorization) have landed; and Phase 5A (module authorization integration) is in
progress. The repository includes
Phase 3 is complete, and Phase 4A (Core identity foundation), Phase 4B (identity HTTP transport),
Phase 4C (Core authorization), and Phase 5A (module authorization integration) have landed. The
repository includes
public module contracts, independently versioned capabilities, static module manifests,
deterministic automatic discovery, compiled server loading, a staged capability registry,
dependency-ordered lifecycle with rollback, module-owned Drizzle table contracts, deterministic
@@ -51,17 +51,21 @@ on every mutation. Roles/groups/teams/tenants, an owner-management HTTP endpoint
accounts/API tokens remain later work. See [Authorization](docs/development/authorization.md) and
[ADR 0013](docs/architecture/decisions/0013-core-authorization-and-owner-bootstrap.md).
Phase 5A (in progress) wires module-declared permissions into that same authorization system: a
version-3 module manifest declares permissions as complete `{id, baseline, description}`
declarations (never a bare string), and `apps/api` discovers every installed module and composes
one immutable platform permission registry — Core's own declarations plus every module's — before
constructing its database pool, Better Auth instance, or HTTP server. A module's declared
permission is then enforceable and grantable through the exact same `requirePermission` middleware
and `/api/v1/grants` HTTP API Core's own permissions already use, with `core.*` reserved and never
Phase 5A wires module-declared permissions into that same authorization system: a version-3 module
manifest declares permissions as complete `{id, baseline, description}` declarations (never a bare
string), and `apps/api` discovers every installed module and composes one immutable platform
permission registry — Core's own declarations plus every module's — before constructing its
database pool, Better Auth instance, or HTTP server. A module's declared permission is then
enforceable and grantable through the exact same `requirePermission` middleware and
`/api/v1/grants` HTTP API Core's own permissions already use, with `core.*` reserved and never
claimable by a module. `pnpm doctor` and `pnpm modules:validate` both validate permission
composition. Module HTTP route registration and relationship-derived grant creation remain later
work. See [Authorization](docs/development/authorization.md#module-permission-composition) and
[Module development](docs/module-development/README.md).
composition. Installing, removing, or editing a module currently requires an API restart; removing
one makes its permission unavailable to new checks and new grants without deleting or revoking any
historical grant or audit row. Module HTTP route registration and relationship-derived grant
creation remain later work. See
[Authorization](docs/development/authorization.md#module-permission-composition),
[Module development](docs/module-development/README.md), and
[ADR 0014](docs/architecture/decisions/0014-module-permission-declarations-and-platform-registry.md).
## Quick start