# 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/` 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.