Phase 1: read-only MVP (memberships, sessions, events, effective permissions, drift report, mapper) #4

Merged
KofTwentyTwo merged 4 commits from feature/phase-1-read-mvp into develop 2026-10-12 11:08:37 +00:00
KofTwentyTwo commented 2026-10-12 11:04:09 +00:00 (Migrated from github.com)

Replaces #2, which GitHub closed when its base branch feature/phase-0-foundations was deleted after #1 squash-merged. Same branch and content; develop is merged in (phase 0 now arrives as #1's squash commit) and the committed Python bytecode is dropped. Original description follows.

Stacked on #1. Retarget it to develop after #1 merges. This is phase 1 of DESIGN.md section 11, the read-only MVP.

Contents

  • Tables under the Identity app:
    • authentikGroupMember: a virtual membership table, served from a group (include_users), a user (groups_obj) or a bounded sweep. Filters: group pk/name, user pk/username, or the key groupPk:userPk. Every member is scope-checked.
    • authentikSession and authentikEvent, both behind identity.audit.read.
  • Effective permissions:
    • GroupGraph + EffectivePermissionResolver (pure): groups and their inherited parents become QQQ permissions.
    • identity.* and catalog wildcards are expanded; unknown names are reported, never granted; cycles are safe.
    • Groups show inherited superuser status and effective permissions; users show effective permissions. If the graph can't be read, they show "Unavailable", never empty.
  • AuthentikGroupPermissionMapper:
    • sign-in permissions from the token's groups claim, plus static fallbacks and bootstrapOperators
    • if Authentik is unreachable, it grants only the fallbacks
    • the kof22 cut-over follows the owner's seed step
  • Identity drift report widget, gated by identity.admin. A standard TABLE widget, so no frontend work. It checks:
    • the server version and blueprint status
    • the service-account shape, and self-minted extra tokens
    • break-glass presence
    • the last human identity admin
    • qqq.io/* attribute validity, including malformed values
    • service-account changes to protected or superuser objects (lockout or compromise detection)
  • Review hardening from two independent reviews (general and silent-failure). Every high finding and most mediums are fixed, with regression tests (ReviewFixesTest). See the CHANGELOG.

Tests (local, CI=true ./mvnw verify)

  • Unit: 68/68, on recorded 2026.8.3 fixtures.
  • Contract: 31/31 on Authentik 2026.8.3. New Phase1ReadContractIT:
    • a real session via the flow executor
    • memberships by group, user and key
    • inherited permissions through a child of identity-admins
    • the drift report run against the live container, where it flags SuperuserFloorIT's lockout probes as ERROR
  • JaCoCo gate met.
  • The phase 0 rehearsal script (docs/cluster-gitops-phase0/rehearse-phase0.sh) passed on a synthetic production-like dump.

CircleCI is not enabled for this new repo yet (owner checklist D1), so these are local results.

Not in this PR

Mirror tables, the group tree and access-matrix widgets, the health widget, and the kof22 mapper cut-over.

🤖 Generated with Claude Code

Replaces #2, which GitHub closed when its base branch `feature/phase-0-foundations` was deleted after #1 squash-merged. Same branch and content; develop is merged in (phase 0 now arrives as #1's squash commit) and the committed Python bytecode is dropped. Original description follows. Stacked on #1. Retarget it to `develop` after #1 merges. This is phase 1 of [DESIGN.md](../blob/develop/docs/DESIGN.md) section 11, the read-only MVP. ## Contents - **Tables** under the Identity app: - `authentikGroupMember`: a virtual membership table, served from a group (`include_users`), a user (`groups_obj`) or a bounded sweep. Filters: group pk/name, user pk/username, or the key `groupPk:userPk`. Every member is scope-checked. - `authentikSession` and `authentikEvent`, both behind `identity.audit.read`. - **Effective permissions:** - `GroupGraph` + `EffectivePermissionResolver` (pure): groups and their inherited parents become QQQ permissions. - `identity.*` and catalog wildcards are expanded; unknown names are reported, never granted; cycles are safe. - Groups show inherited superuser status and effective permissions; users show effective permissions. If the graph can't be read, they show "Unavailable", never empty. - **`AuthentikGroupPermissionMapper`:** - sign-in permissions from the token's `groups` claim, plus static fallbacks and `bootstrapOperators` - if Authentik is unreachable, it grants only the fallbacks - the kof22 cut-over follows the owner's seed step - **Identity drift report** widget, gated by `identity.admin`. A standard TABLE widget, so no frontend work. It checks: - the server version and blueprint status - the service-account shape, and self-minted extra tokens - break-glass presence - the last human identity admin - `qqq.io/*` attribute validity, including malformed values - service-account changes to protected or superuser objects (lockout or compromise detection) - **Review hardening** from two independent reviews (general and silent-failure). Every high finding and most mediums are fixed, with regression tests (`ReviewFixesTest`). See the CHANGELOG. ## Tests (local, `CI=true ./mvnw verify`) - Unit: **68/68**, on recorded 2026.8.3 fixtures. - Contract: **31/31** on Authentik 2026.8.3. New `Phase1ReadContractIT`: - a real session via the flow executor - memberships by group, user and key - inherited permissions through a child of `identity-admins` - the drift report run against the live container, where it flags `SuperuserFloorIT`'s lockout probes as ERROR - JaCoCo gate met. - The phase 0 rehearsal script (`docs/cluster-gitops-phase0/rehearse-phase0.sh`) passed on a synthetic production-like dump. CircleCI is not enabled for this new repo yet (owner checklist D1), so these are local results. ## Not in this PR Mirror tables, the group tree and access-matrix widgets, the health widget, and the kof22 mapper cut-over. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.