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.
Files:
migrations/versions/20260716_10_rbac.pyapp/core/system/models.pyCreate: 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.
Files:
app/commands/bootstrap_admin.pytests/test_bootstrap_admin.pydeploy/docker/postgres/init/010-local-test-user.sqlModify: 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.
Files:
app/api/system/routes.pyapp/core/system/auth.pyapp/core/system/tokens.pyCreate: 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.
Files:
app/core/system/permissions.pyapp/api/*/routes.pyCreate: 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.
Files:
app/api/system/users.pyapp/api/system/__init__.pytests/test_user_management_api.pyfrontend/src/views/systemManage/user/index.vueCreate: 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.
Files:
frontend/src/store/modules/user.jsfrontend/src/router/index.jsfrontend/src/views/login/components/login.vueCreate: 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.