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