crabidy/quality/roles-auth.md

60 lines
2.6 KiB
Markdown

# Quality gates — roles and rights
LLM-verified gates for `architecture/roles-auth.md`. Automatic tests
live in `crabidy-server/src/auth.rs`, `crabidy-server/src/main.rs`
(hash helper) and `cbd-tui/src/rpc.rs`.
## Security posture
- [x] Fail-closed everywhere: an unknown/future gRPC method requires
owner; a present-but-malformed `crabidy-server.toml` aborts server
startup instead of silently running open; a missing file (or empty
`[auth]`) is the documented open mode.
- [x] No panics on request input: malformed `authorization` headers
(bad base64, missing colon, non-UTF-8, wrong scheme), unknown
role names, and oversized values all produce `UNAUTHENTICATED`,
never a panic.
- [x] Indistinguishable failures: wrong user and wrong password both
answer plain `UNAUTHENTICATED` with the same message.
- [x] Secrets redacted: passwords, authorization header values, and
PHC hashes never appear in logs, traces, or error messages
(including the `hash-password` helper and TUI logs).
- [x] Authorization is enforced in exactly one place (the tower
layer), before any handler runs; RPC handlers did not change.
## Semantics
- [x] Rights matrix implemented as specified: appender = reads +
`Append` + `CreateLibraryNode`; queue-owner adds every queue and
playback verb; owner-only = `CaptureLibraryNode`, `SaveQueue`,
`RenameLibraryNode`, `DeleteLibraryNode`. Higher roles include
lower ones. A test pins the full method list of the proto service
so an unmapped new RPC fails the suite.
- [x] Valid credentials with an insufficient role get
`PERMISSION_DENIED` (not `UNAUTHENTICATED`).
- [x] No `[auth]` hashes ⇒ exactly today's behavior: no header
required, all methods allowed.
- [x] A role without a configured hash cannot authenticate.
## Performance
- [x] Argon2 verification runs once per credential: successful
verifications are cached (header value → role) and the cache is
only fed by successes, keeping it bounded by the number of valid
credentials.
## Client
- [x] Without configured credentials the TUI sends no header
(zero-config local use unchanged); with credentials, every
request — including update-stream reconnects — carries the same
`authorization: Basic` header.
- [x] The client config documents that `password` is plaintext and the
file must be kept private.
## Tooling
- [x] `crabidy-server hash-password` reads the password from stdin
(nothing echoed by the tool itself), prints only the PHC string,
and its output verifies against the same server code path.