2026-07-16-rbac-authentication.md 4.6 KB

RBAC Authentication Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:test-driven-development and superpowers:executing-plans to implement this plan task-by-task.

Goal: Replace legacy authentication with administrator-managed users and admin/editor/viewer authorization, with no public self-registration.

Architecture: PostgreSQL is the identity source. A system CLI initializes exactly one first administrator; administrators create later users. Flask decorators enforce permissions at the API boundary and frontend guards reflect, but do not replace, backend authorization.

Tech Stack: Flask, SQLAlchemy, PostgreSQL, Argon2id, JWT, Vue 2, pytest.


Task 1: Add normalized identity tables

Files:

  • Create: migrations/versions/20260716_10_rbac.py
  • Create: app/core/system/models.py
  • Create: tests/test_rbac_schema.py

  • [ ] Test uniqueness, disabled users, the fixed admin/editor/viewer role seed and cascading user_roles cleanup.

  • [ ] Create UUID-based users, roles, user_roles and auth_audit_events; store only password_hash.

  • [ ] Add a data-report command that lists legacy accounts requiring password reset; do not copy reversible password values.

  • [ ] Verify migration against a copy of local test data and keep production column removal out of this migration.

Task 2: Implement first-administrator bootstrap

Files:

  • Create: app/commands/bootstrap_admin.py
  • Create: tests/test_bootstrap_admin.py
  • Modify: deploy/docker/postgres/init/010-local-test-user.sql
  • Modify: deploy/docker/README.md

  • [ ] Test successful first creation, rejection when an administrator already exists, weak-password rejection and secret-free logs.

  • [ ] Read username/password from CLI prompt or environment injected at runtime; hash with Argon2id.

  • [ ] Remove the legacy base64 seed once the new flow is active and run the bootstrap command from an explicit local setup step.

  • [ ] Verify repeated Docker startup cannot silently replace the administrator.

Task 3: Replace login and current-user endpoints

Files:

  • Modify: app/api/system/routes.py
  • Modify: app/core/system/auth.py
  • Create: app/core/system/tokens.py
  • Create: tests/test_auth_api.py

  • [ ] Test correct login, wrong password, disabled user, expired/tampered token and GET /api/system/auth/me.

  • [ ] Return a short-lived bearer token containing sub, roles, iat, exp and jti; do not place profile data or permissions in local storage beyond what UI needs.

  • [ ] Rate-limit repeated failures and record an audit event without passwords or tokens.

  • [ ] Remove GET /auth/user/<username> as an authentication mechanism after frontend migration.

Task 4: Add backend permission policy

Files:

  • Create: app/core/system/permissions.py
  • Modify: app/api/*/routes.py
  • Create: tests/test_permission_matrix.py

  • [ ] Define named permissions for read governance, edit governance, approve review, manage users, activate workflow and operate orders.

  • [ ] Test every registered non-health route has an explicit anonymous/read/edit/admin policy; unclassified routes fail the test.

  • [ ] Apply @require_permissions(...) decorators and return 401 for missing identity, 403 for insufficient permission.

  • [ ] Keep /api/system/health public and ensure diagnostic responses contain no sensitive configuration.

Task 5: Add administrator user management

Files:

  • Create: app/api/system/users.py
  • Modify: app/api/system/__init__.py
  • Create: tests/test_user_management_api.py
  • Create: frontend/src/views/systemManage/user/index.vue
  • Create: frontend/src/api/users.js

  • [ ] Test administrator create/list/disable/reset-role flows and prove editor/viewer receive 403.

  • [ ] Implement POST/GET /api/system/users, PUT /users/{id} and PUT /users/{id}/roles; omit any registration endpoint.

  • [ ] Prevent disabling or removing the last active administrator.

  • [ ] Build a minimal user page accessible only to administrators.

Task 6: Apply frontend guards and acceptance tests

Files:

  • Modify: frontend/src/store/modules/user.js
  • Modify: frontend/src/router/index.js
  • Modify: frontend/src/views/login/components/login.vue
  • Create: tests/e2e/rbac.spec.js

  • [ ] Load /auth/me on application startup and derive visible navigation/actions from permissions.

  • [ ] Clear tokens on 401, preserve the intended route, and avoid treating hidden buttons as security enforcement.

  • [ ] Run browser acceptance for all three roles, direct URL access, expired sessions and administrator-created users.

  • [ ] Regenerate OpenAPI and update the permission matrix documentation.