Files
agentic-mobile-control/openspec/changes/cloud-console-user-authentication/tasks.md
T

57 lines
6.8 KiB
Markdown

## 1. User model, persistence, and migration
- [x] 1.1 Add the maintained Argon2id password-hashing dependency to the Cloud Platform package and refresh the shared lockfile
- [x] 1.2 Define user, role, session, login-throttle, and authentication-audit domain models plus the fixed role-to-scope mapping and `users:admin` scope
- [x] 1.3 Extend the persistence port with account lookup/list/create/update, password/auth-version update, session create/authenticate/revoke, throttle, audit, and bounded cleanup operations
- [x] 1.4 Add SQLAlchemy rows, uniqueness/index/foreign-key constraints, and conversion helpers for users, sessions, throttle buckets, and audit events
- [x] 1.5 Implement all user-auth persistence operations in `SQLAlchemyCloudRepository` with equivalent SQLite and PostgreSQL behavior and atomic last-enabled-admin protection
- [x] 1.6 Add Alembic revision `0003` for the user-auth tables and indexes, including an explicit destructive downgrade
- [x] 1.7 Add repository and migration tests for normalized username conflicts, session lookup/revocation/expiry, throttle windows, audit redaction fields, last-admin protection, upgrade, and downgrade
## 2. Password, session, and authentication services
- [x] 2.1 Implement the injectable Argon2id `PasswordHasher`, password policy validation, dummy verification, and successful-login rehash behavior without secret-bearing logs or representations
- [x] 2.2 Implement user creation/update/reset/change-password services with authentication-version increments, forced-password-change handling, role scopes, and affected-session revocation
- [x] 2.3 Implement opaque session and CSRF generation, digest-only persistence, idle/absolute TTL checks, bounded touch/cleanup, logout, and secure cookie set/clear helpers
- [x] 2.4 Implement temporary username/client-bucket login throttling, trusted-proxy-aware address selection, generic failures, successful-login reset, and bounded expired-state cleanup
- [x] 2.5 Implement safe authentication audit recording for login/logout/password/user/session outcomes and add tests proving passwords, hashes, cookies, CSRF values, and bearer tokens cannot enter audit payloads
- [x] 2.6 Implement `UserSessionAuthProvider` and compose user principals into the existing auth chain without changing configured bearer, Host-bound, or enrollment provider semantics
- [x] 2.7 Enforce session-bound CSRF on unsafe cookie-authenticated requests while exempting requests authenticated by an explicit bearer header
- [x] 2.8 Extend `CloudControlConfig` with bounded session/throttle/cookie/trusted-proxy settings, production-secure defaults, and validation tests
## 3. Authentication, user administration, SDK, and CLI surfaces
- [x] 3.1 Add non-secret request/response models and `/v1/auth/login`, `/v1/auth/me`, `/v1/auth/logout`, and `/v1/auth/password` handlers with forced-password-change restrictions
- [x] 3.2 Add bounded `/v1/users` list/create/update, password-reset, and session-revocation handlers protected by `users:admin`
- [x] 3.3 Wire the user-auth services and routers into Cloud API lifespan/composition so repository access remains unavailable outside lifespan and readiness reflects required schema/configuration
- [x] 3.4 Extend `CloudClient` with cookie-preserving authentication/password methods and bearer-compatible user-administration methods, including CSRF handling for session writes
- [x] 3.5 Add the `device-cloud-admin` entry point with interactive `getpass` create/reset commands plus enable and session-revoke recovery commands, schema checks, non-secret output, and no password command-line option
- [x] 3.6 Add API/SDK/CLI tests for successful and failed login, generic errors, throttle expiry, cookie flags, CSRF, session expiry/revocation, role scopes, forced password change, user lifecycle, last-admin protection, and schema failures
- [x] 3.7 Add compatibility regression tests proving existing public bearer clients, static Host credentials, dynamically enrolled Hosts, and enrollment tokens retain their previous authorization behavior
## 4. Cloud Console account experience
- [x] 4.1 Refactor `cloud-console/src/api.ts` into explicit user-session and compatibility-token modes, using `credentials: "include"`, session CSRF headers, and distinct `401` versus `403` handling
- [x] 4.2 Replace the default token gate with username/password login and a secondary “Use API token” flow that preserves the existing tab-scoped token behavior
- [x] 4.3 Add current-user initialization, authenticated account menu, logout, session-expired messaging, password change, and forced-temporary-password routing to the Console shell
- [x] 4.4 Add an admin-only Users view for bounded listing, creation, role/enabled updates, password reset, and session revocation with immediate clearing of all password fields
- [x] 4.5 Hide actions/navigation from principals lacking their required scopes while continuing to surface backend `403` responses as the authoritative decision
- [ ] 4.6 Add frontend tests for session bootstrap, login failure, CSRF write requests, `401` session loss, preserved session on `403`, token fallback, forced password change, and admin/non-admin user navigation
## 5. Packaging, deployment, and documentation
- [x] 5.1 Ensure the Python wheel and Docker image contain the Argon2 dependency, `device-cloud-admin` entry point, migration, and rebuilt Cloud Console assets
- [x] 5.2 Update Compose examples and `.env.example` with non-secret session/throttle/cookie configuration while keeping initial passwords out of environment and Compose files
- [x] 5.3 Update `docs/CLOUD_DEPLOYMENT.md` with HTTPS requirements, migration order, interactive first-admin creation, role semantics, login/session behavior, recovery, token fallback, rotation, and rollback
- [x] 5.4 Update `cloud-console/README.md` for same-origin production login and credentialed Vite development with exact-origin CORS
- [x] 5.5 Reconcile the active `cloud-console` token-only requirement before archive so account login is primary and bearer entry is explicitly compatibility-only
## 6. Verification
- [x] 6.1 Run formatting, lint/static checks, secret-focused review, and the complete non-integration Python test suite across all workspace packages
- [ ] 6.2 Run the PostgreSQL-backed repository, concurrency, and Alembic upgrade/downgrade tests for user/session/throttle/admin invariants
- [x] 6.3 Run Cloud Console dependency install, unit tests, type-check, and production build
- [x] 6.4 Run `openspec validate cloud-console-user-authentication --strict` and resolve all artifact/spec errors
- [ ] 6.5 Manually verify a Compose deployment over HTTPS: bootstrap admin, forced password change, viewer/operator/admin authorization, session expiry/revocation, login throttling, logout, and browser restart
- [ ] 6.6 Manually verify configured bearer `CloudClient` and Host Agent flows alongside user login, then inspect logs/audit rows to confirm no credential material is emitted