Moves the Authentik qbit to its v1: the full user lifecycle and management of groups and permissions, inside QQQ (spec QRun-IO/qqq#1065, revision 4; owner decisions of 2026-10-12: all recommendations accepted). Builds on the merged rename PR #6.
What is built
Writes through the Authentik API (never its DB), behind the features USERS, GROUPS, MEMBERSHIP, CREDENTIALS, SESSIONS. Read-only stays the default; readOnly is a hard kill switch.
Actions as standard streamed-ETL table and record actions (Review = dry run, then Result), never in the nav: Create User, Invite User, Edit User, Deactivate/Reactivate User, Add To Group, Remove From Group, Send Password Reset Email, Reset MFA, Revoke App Passwords, Revoke Sessions, Create Group, Edit Group, Edit Permissions And App Access, Add/Remove Members, Cancel Invitation, Approve And Apply, Reject.
Safety (spec 5.4), checked at Review and again at execute, against live Authentik data and the operator's live groups (not the session claim): subset (no escalation) rule, protected accounts and superuser groups, no self-edits, last-administrator protection, reasons, typed confirmations (and a typed count above 25), a 100-target cap, stale checks by fingerprint, attribute edits that merge only the qqq.io/* keys into the current attributes, and two-person approval for granting authentik.*.
Audit: authentik_admin_action row written before the call (no row, no call), plus an Authentik custom_qqq_admin_action event naming the human operator. authentik_approval_request for second-person requests. DDL in docs/schema.sql.
Screens: the authentikHome dashboard (needs attention, people, groups and permissions, recent changes, connection), the main tables in the nav, and sessions, tokens (never a key), events, bindings, roles, blueprints, memberships as child lists on their parents. New read tables: application, policy_binding, blueprint, role, token, invitation.
Only AuthentikAdmin can change Authentik: AuthentikActionUtil.write needs a WriteAuthorization that only AuthentikGuard.authorize can mint (an architecture test pins the call sites).
Fixes found on the way
A client count returned no distinct count, so process Reviews showed no total; group lists now carry member pks.
Contract tests showed: recovery_email needs the brand to have a recovery flow, plus the role's add_user (DRF maps POST to add), reset_user_password and view_emailstage; MFA devices come back as a bare array. All documented in the README and the owner checklist (new item 12).
Not in this PR (listed in docs/STATUS.md)
The Authentik webhook/ESB trigger/inbox, the local mirror tables and reconcile, the access-matrix and group-tree widgets (need Next UI widgets), snapshot export, RBAC (phase 4), the Alerts producer integration (QRun-IO/qqq#1090). Users and groups are API-backed, so Quick Search is the table's own live search.
Tests
CI=true ./mvnw verify: 128 unit tests (rules on an in-memory Authentik, processes through RunProcessAction, app and home) and 40 contract tests on Authentik 2026.8.3 (9 new write tests: user create with the recovery email arriving in Mailpit, memberships, permission-attribute merge, group create/edit, deactivate with app-password revocation that spares API tokens, edit user, password reset, invite/cancel, MFA reset), all green; checkstyle and the JaCoCo gate pass.
Moves the Authentik qbit to its v1: the full user lifecycle and management of groups and permissions, inside QQQ (spec QRun-IO/qqq#1065, revision 4; owner decisions of 2026-10-12: all recommendations accepted). Builds on the merged rename PR #6.
## What is built
- **Writes through the Authentik API** (never its DB), behind the features `USERS`, `GROUPS`, `MEMBERSHIP`, `CREDENTIALS`, `SESSIONS`. Read-only stays the default; `readOnly` is a hard kill switch.
- **Actions** as standard streamed-ETL table and record actions (Review = dry run, then Result), never in the nav: Create User, Invite User, Edit User, Deactivate/Reactivate User, Add To Group, Remove From Group, Send Password Reset Email, Reset MFA, Revoke App Passwords, Revoke Sessions, Create Group, Edit Group, Edit Permissions And App Access, Add/Remove Members, Cancel Invitation, Approve And Apply, Reject.
- **Safety** (spec 5.4), checked at Review and again at execute, against live Authentik data and the operator's live groups (not the session claim): subset (no escalation) rule, protected accounts and superuser groups, no self-edits, last-administrator protection, reasons, typed confirmations (and a typed count above 25), a 100-target cap, stale checks by fingerprint, attribute edits that merge only the `qqq.io/*` keys into the current attributes, and two-person approval for granting `authentik.*`.
- **Audit**: `authentik_admin_action` row written before the call (no row, no call), plus an Authentik `custom_qqq_admin_action` event naming the human operator. `authentik_approval_request` for second-person requests. DDL in `docs/schema.sql`.
- **Screens**: the `authentikHome` dashboard (needs attention, people, groups and permissions, recent changes, connection), the main tables in the nav, and sessions, tokens (never a key), events, bindings, roles, blueprints, memberships as child lists on their parents. New read tables: application, policy_binding, blueprint, role, token, invitation.
- Only `AuthentikAdmin` can change Authentik: `AuthentikActionUtil.write` needs a `WriteAuthorization` that only `AuthentikGuard.authorize` can mint (an architecture test pins the call sites).
## Fixes found on the way
- A client count returned no distinct count, so process Reviews showed no total; group lists now carry member pks.
- Contract tests showed: `recovery_email` needs the brand to have a recovery flow, plus the role's `add_user` (DRF maps POST to add), `reset_user_password` and `view_emailstage`; MFA devices come back as a bare array. All documented in the README and the owner checklist (new item 12).
## Not in this PR (listed in docs/STATUS.md)
The Authentik webhook/ESB trigger/inbox, the local mirror tables and reconcile, the access-matrix and group-tree widgets (need Next UI widgets), snapshot export, RBAC (phase 4), the Alerts producer integration (QRun-IO/qqq#1090). Users and groups are API-backed, so Quick Search is the table's own live search.
## Tests
`CI=true ./mvnw verify`: 128 unit tests (rules on an in-memory Authentik, processes through `RunProcessAction`, app and home) and 40 contract tests on Authentik 2026.8.3 (9 new write tests: user create with the recovery email arriving in Mailpit, memberships, permission-attribute merge, group create/edit, deactivate with app-password revocation that spares API tokens, edit user, password reset, invite/cancel, MFA reset), all green; checkstyle and the JaCoCo gate pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Moves the Authentik qbit to its v1: the full user lifecycle and management of groups and permissions, inside QQQ (spec QRun-IO/qqq#1065, revision 4; owner decisions of 2026-10-12: all recommendations accepted). Builds on the merged rename PR #6.
What is built
USERS,GROUPS,MEMBERSHIP,CREDENTIALS,SESSIONS. Read-only stays the default;readOnlyis a hard kill switch.qqq.io/*keys into the current attributes, and two-person approval for grantingauthentik.*.authentik_admin_actionrow written before the call (no row, no call), plus an Authentikcustom_qqq_admin_actionevent naming the human operator.authentik_approval_requestfor second-person requests. DDL indocs/schema.sql.authentikHomedashboard (needs attention, people, groups and permissions, recent changes, connection), the main tables in the nav, and sessions, tokens (never a key), events, bindings, roles, blueprints, memberships as child lists on their parents. New read tables: application, policy_binding, blueprint, role, token, invitation.AuthentikAdmincan change Authentik:AuthentikActionUtil.writeneeds aWriteAuthorizationthat onlyAuthentikGuard.authorizecan mint (an architecture test pins the call sites).Fixes found on the way
recovery_emailneeds the brand to have a recovery flow, plus the role'sadd_user(DRF maps POST to add),reset_user_passwordandview_emailstage; MFA devices come back as a bare array. All documented in the README and the owner checklist (new item 12).Not in this PR (listed in docs/STATUS.md)
The Authentik webhook/ESB trigger/inbox, the local mirror tables and reconcile, the access-matrix and group-tree widgets (need Next UI widgets), snapshot export, RBAC (phase 4), the Alerts producer integration (QRun-IO/qqq#1090). Users and groups are API-backed, so Quick Search is the table's own live search.
Tests
CI=true ./mvnw verify: 128 unit tests (rules on an in-memory Authentik, processes throughRunProcessAction, app and home) and 40 contract tests on Authentik 2026.8.3 (9 new write tests: user create with the recovery email arriving in Mailpit, memberships, permission-attribute merge, group create/edit, deactivate with app-password revocation that spares API tokens, edit user, password reset, invite/cancel, MFA reset), all green; checkstyle and the JaCoCo gate pass.🤖 Generated with Claude Code