# Plan — roles and rights From `architecture/roles-auth.md` and `quality/roles-auth.md`. - [x] **Deps**: workspace `argon2` (with `std`), `http`, `tower`; `crabidy-server` gains `argon2`, `base64`, `http`, `tower`, `clap`; `cbd-tui` gains `base64`. Verify: workspace builds. - [x] **Server settings** (`crabidy-server/src/settings.rs`): `ServerSettings { auth: AuthSettings }`, `AuthSettings { owner, queue_owner, queue_appender: Option }`; `load(config_dir)` — absent file ⇒ defaults, malformed file ⇒ startup error. Verify: unit tests for all three cases. - [x] **Auth core** (`crabidy-server/src/auth.rs`): `Role` (ordered), `minimum_role(method) -> Role` default-deny table, `Authenticator` (parse Basic header, argon2 verify, success cache, disabled mode). Verify: unit tests — header parsing never panics, wrong user/password indistinguishable, matrix samples per role, unknown method ⇒ owner, cache fed only by successes, disabled mode allows all without header. - [x] **Tower layer** (`auth.rs`): `AuthLayer`/`AuthService` checking `authorization` against the method's minimum role before the inner service; denials answer trailers-only via `Status::into_http()`. Verify: service-level tests with a counting inner service (deny short-circuits, allow forwards, unauthenticated vs permission-denied codes). - [x] **Wire-up** (`lib.rs::serve`): load settings, fail startup on malformed config, install the layer. Verify: existing tests still pass; layer test covers enforcement. - [x] **hash-password** (`main.rs` + clap): subcommand reads stdin, prints PHC string; round-trip test hash → authenticator accepts. - [x] **Client** (`cbd-tui`): `user`/`password` config options (and flags), auth interceptor attaching a precomputed Basic header to every request, type alias for the intercepted client. Verify: unit tests — no creds ⇒ no header, creds ⇒ header present. - [x] **Docs**: root README (config table row, `cbd-tui.toml` options, security note), new `crabidy-server.toml` section; architecture cross-links. Verify: markdownlint. - [x] **Gates**: run the full suite + clippy + fmt; check off `quality/roles-auth.md`; write `plan/summary.md` section.