Skip to content

feat(admin): console user management with user types - #60

Closed
jogunjobi wants to merge 1 commit into
mainfrom
feat/console-users
Closed

jogunjobi wants to merge 1 commit into
mainfrom
feat/console-users

Conversation

@jogunjobi

Copy link
Copy Markdown
Contributor

Second of two PRs (the first, #59, added the viewer role). Feedback from evaluators: after deployment an administrator could not add more console users; the only way was SQL.

What it adds

  • A Console Users page (sidebar, administrators only) and /api/admin-users: list, add, edit, reset password, disable, enable, delete.
  • User types: Administrator (owner), Read-write (security_admin), Read-only (viewer), Custom (any of the fine-grained roles; never owner/admin).
  • First password: generated (20 chars without look-alikes, about 115 bits), shown once with no-store caching, and must be changed at first sign-in. Reset does the same. With SSO on, non-administrators sign in with SSO (subject required, no password); administrators still get a break-glass password.
  • Guards: an administrator cannot change, disable, reset or delete their own account here; the last enabled administrator cannot be demoted, disabled or deleted; delete only after disable. Changes are serialised with an advisory lock.
  • Sessions: role, enabled and password changes end the user's sessions on their next request (existing authorization_version trigger).
  • Audit: admin_user.create|update|reset_password|disable|enable|delete, strict (fails closed), before/after summaries with no password, hash or SSO subject.
  • Only owner/admin reach the new routes (empty rules at the top of both RBAC tables). Rules live in admin/admin_users.py, shared by API and pages. No migration.

Tests

  • Unit: 35 service tests (types, validation, password policy, every guard, no secrets in output or audit), 16 route tests through real sessions (RBAC for security_admin/viewer/auditor/policy_admin, disable ends an open session, reveal shown once, errors in place).
  • e2e test_admin_user_management.py (4 tests): read-only user signs in with the temporary password, is held until they change it, reads pages, is refused writes and console users; read-write user can write but not manage users or map console SSO subjects; disable ends the session; delete needs disable; reset forces a new choice.
  • Browser certification covers the list and form pages. Mutations caught: last-administrator guard, self guard, admin-users rule opened to security_admin, custom roles unchecked.
  • Local: lint, type, 3447 unit/dashboard/integration, full e2e 254 passed, browser 22 passed, docs-check.

Docs: rewritten Manage admin users guide (types, one-time password, reset, disable vs delete, guards, SSO, SQL recovery appendix), admin-access link, regenerated admin-roles/admin-api/OpenAPI, CHANGELOG.

Administrators can now add and manage the people who sign in to the console,
from a Console Users page and from /api/admin-users, instead of with SQL.

- User types: Administrator (owner), Read-write (security_admin),
  Read-only (viewer), or Custom (chosen roles; never owner or admin).
- A new user and a password reset get a generated temporary password,
  shown once, that must be changed at first sign-in. With SSO on,
  non-administrators sign in with SSO and get no password.
- Edit type, roles, email and SSO subject; reset password; disable and
  enable; delete only once disabled.
- An administrator cannot change, disable, reset or delete their own
  account here, and the last enabled administrator cannot be removed;
  changes are serialised with an advisory lock.
- Role, enabled and password changes end the user's sessions through the
  existing authorization_version trigger. Every change is strictly audited
  as admin_user.*; no response or audit row carries a password or hash.

Only owner and admin reach the new routes. The rules live in
admin/admin_users.py, shared by the API and the pages.
@jogunjobi
jogunjobi requested a review from a team as a code owner October 15, 2026 05:36
@jogunjobi jogunjobi added the e2e Run the end-to-end suite on this pull request label Oct 15, 2026
@jogunjobi jogunjobi closed this Oct 15, 2026
@jogunjobi jogunjobi reopened this Oct 15, 2026
@jogunjobi

Copy link
Copy Markdown
Contributor Author

Landed on main as 803ef07 (squashed; change identical to the PR diff).

jogunjobi added a commit that referenced this pull request Oct 16, 2026
Administrators can now add and manage the people who sign in to the console,
from a Console Users page and from /api/admin-users, instead of with SQL.

- User types: Administrator (owner), Read-write (security_admin),
  Read-only (viewer), or Custom (chosen roles; never owner or admin).
- A new user and a password reset get a generated temporary password,
  shown once, that must be changed at first sign-in. With SSO on,
  non-administrators sign in with SSO and get no password.
- Edit type, roles, email and SSO subject; reset password; disable and
  enable; delete only once disabled.
- An administrator cannot change, disable, reset or delete their own
  account here, and the last enabled administrator cannot be removed;
  changes are serialised with an advisory lock.
- Role, enabled and password changes end the user's sessions through the
  existing authorization_version trigger. Every change is strictly audited
  as admin_user.*; no response or audit row carries a password or hash.

Only owner and admin reach the new routes. The rules live in
admin/admin_users.py, shared by the API and the pages.
@jogunjobi jogunjobi closed this Oct 16, 2026
@jogunjobi
jogunjobi deleted the feat/console-users branch October 16, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

e2e Run the end-to-end suite on this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant