feat(policy): full access ("*") statement and maintenance policy API #32

Merged
KofTwentyTwo merged 3 commits from feature/policy-full-access into develop 2026-10-14 20:42:07 +00:00
KofTwentyTwo commented 2026-10-14 20:17:37 +00:00 (Migrated from github.com)

Owner request (2026-10-14): "make sure that my group has a special * access policy that allows for full access".

Full access

  • {"Effect":"Allow","Action":["*"],"Resource":["*"]} means Full access (all current and future resources).
  • It is expanded whenever permissions are computed: at sign-in, in the resolver, in Compare Access, and in the member preview. Tables, processes, apps, reports, widgets and features added later are covered with no policy edit.
  • The expansion is PermissionsHelper.getAllAvailablePermissions, plus the qbit's own catalog, plus every authentik.* permission.
  • Resource * with any other action rejects the document. Action * on a named resource keeps today's meaning (the five standard actions).
  • The canonical form is that single statement.
  • Saving it requires the operator to hold the full set.
  • The editor payload gets fullAccess. The Next checkbox is a separate PR.
  • Documented in POLICY-FORMAT.md ("Full access") and DESIGN.md §12.

Maintenance API

AuthentikMaintenance.applyPolicy(apiBackendName, groupName, policyJson, operatorName, reason) lets reviewed host code set a group's policy as a named maintenance operator (run-once:… or maintenance:…), never as a system session. kof22 will use it from a run-once job to give kof22-admins full access.

  • It runs the same Save Policy plan and execute: the audit row is written before the Authentik call, and the custom Authentik event is posted.
  • All guardrails apply: protected and superuser groups, scope, read-only mode, the POLICIES feature, the stale check, and optional two-person approval.
  • An equivalent policy returns NO_CHANGE with no write.
  • It is a plain Java API; nothing is exposed over HTTP.

Tests

291 unit tests pass. They include PolicyFullAccessTest (parsing, the canonical form, round-trip, a resource added after the document was written is still granted, the mapper and graph paths, the subset rule) and AuthentikMaintenanceTest (10 cases: audit row and exact reason, idempotence, approval, validation, stale state, context restore, system writes still refused).

🤖 Generated with Claude Code

Owner request (2026-10-14): "make sure that my group has a special * access policy that allows for full access". ## Full access - `{"Effect":"Allow","Action":["*"],"Resource":["*"]}` means **Full access (all current and future resources)**. - It is expanded whenever permissions are computed: at sign-in, in the resolver, in Compare Access, and in the member preview. Tables, processes, apps, reports, widgets and features added later are covered with no policy edit. - The expansion is `PermissionsHelper.getAllAvailablePermissions`, plus the qbit's own catalog, plus every `authentik.*` permission. - Resource `*` with any other action rejects the document. Action `*` on a named resource keeps today's meaning (the five standard actions). - The canonical form is that single statement. - Saving it requires the operator to hold the full set. - The editor payload gets `fullAccess`. The Next checkbox is a separate PR. - Documented in POLICY-FORMAT.md ("Full access") and DESIGN.md §12. ## Maintenance API `AuthentikMaintenance.applyPolicy(apiBackendName, groupName, policyJson, operatorName, reason)` lets reviewed host code set a group's policy as a named maintenance operator (`run-once:…` or `maintenance:…`), never as a system session. kof22 will use it from a run-once job to give **kof22-admins** full access. - It runs the **same** Save Policy plan and execute: the audit row is written before the Authentik call, and the custom Authentik event is posted. - All guardrails apply: protected and superuser groups, scope, read-only mode, the POLICIES feature, the stale check, and optional two-person approval. - An equivalent policy returns NO_CHANGE with no write. - It is a plain Java API; nothing is exposed over HTTP. ## Tests 291 unit tests pass. They include `PolicyFullAccessTest` (parsing, the canonical form, round-trip, a resource added after the document was written is still granted, the mapper and graph paths, the subset rule) and `AuthentikMaintenanceTest` (10 cases: audit row and exact reason, idempotence, approval, validation, stale state, context restore, system writes still refused). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
KofTwentyTwo commented 2026-10-14 20:31:39 +00:00 (Migrated from github.com)

Added AuthentikQBitConfig.withFullAccessHostPermissions(qInstance -> names). PermissionsHelper.getAllAvailablePermissions cannot list custom-checker and named permissions (for example cdn.purge and email.send), and kof22 found 63 of its admin permissions missing from the * expansion. With this hook a host declares those names. They are computed at each expansion, and only for the instance that holds that runtime's backend. Covered by PolicyFullAccessTest.hostDeclaredPermissionsJoinFullAccessForTheirInstanceOnly and documented in POLICY-FORMAT.md and the CHANGELOG. Consumer: KofTwentyTwo/Website-Backend#230.

Added `AuthentikQBitConfig.withFullAccessHostPermissions(qInstance -> names)`. `PermissionsHelper.getAllAvailablePermissions` cannot list custom-checker and named permissions (for example `cdn.purge` and `email.send`), and kof22 found 63 of its admin permissions missing from the `*` expansion. With this hook a host declares those names. They are computed at each expansion, and only for the instance that holds that runtime's backend. Covered by `PolicyFullAccessTest.hostDeclaredPermissionsJoinFullAccessForTheirInstanceOnly` and documented in POLICY-FORMAT.md and the CHANGELOG. Consumer: KofTwentyTwo/Website-Backend#230.
Sign in to join this conversation.