phase-4/core-authorization #10

Merged
Zayin_Admin merged 4 commits from phase-4/core-authorization into main 2026-07-23 16:52:40 +00:00
Owner

feat: add core authorization and owner bootstrap

feat: add core authorization and owner bootstrap
Zayin_Admin added 4 commits 2026-07-23 16:49:56 +00:00
Wires Core's identity and authorization domains into apps/api over one
shared, validated PostgreSQL pool; adds an explicit, single-use,
concurrency-safe platform-owner bootstrap CLI; adds a smallest-possible
immutable permission registry with one Core-owned restricted permission
(core.authorization.grants.manage); and adds reusable Hono authorization
enforcement plus a narrowly scoped /api/v1/grants HTTP API for managing
explicit grants only, gated by an exact trusted Origin on every mutation.
Adds ADR 0013 documenting the durable Phase 4C decisions (permission
registry, evaluator baselines, grant/scope semantics, platform-owner
bootstrap, shared database pool, Origin enforcement, and what remains
deferred), cross-links it from the authorization/README docs, and
refreshes the pnpm doctor no-DATABASE_URL example output in README.md
and repository-workflow.md to include the authorization migration.
fix: enforce registered authorization permissions
CI / verify (pull_request) Successful in 25s
CI / infrastructure-smoke (pull_request) Successful in 11s
CI / migration-smoke (pull_request) Successful in 27s
df2af0a3e0
Two related fail-closed gaps let a well-formed but never-declared
permission id slip through:

- POST /api/v1/grants created explicit grants for any well-formed
  PermissionId without checking the injected permission registry,
  allowing dormant grants for invented identifiers that could become
  effective the moment those identifiers were registered later.
- createAuthorizationEvaluator validated the permission id only inside
  the restricted-baseline branch, so a malformed permission combined
  with the public or authenticated baseline could still return allowed.

Both now fail closed: the grants route checks the target permission
against the trusted registry before calling store.createGrant (sanitized
403, no store or audit write), and the evaluator validates permission
shape before any baseline is allowed to return an allowed decision,
without adding a registry dependency to the evaluator itself.

The live integration lifecycle test switched from an unregistered
calendar.events.read to the registered core.authorization.grants.manage
permission, since module permission registration does not exist yet.
Zayin_Admin merged commit 79aaab93b6 into main 2026-07-23 16:52:40 +00:00
Zayin_Admin deleted branch phase-4/core-authorization 2026-07-23 16:52:40 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Zayin/Ekklesia#10