feat(auth): brahman-auth — autenticación del escritorio (PAM + mock)

Base del DM/greeter de carmen. Contrato Authenticator agnóstico:
authenticate(usuario, secreto) -> UserInfo (uid/gid/home/shell).
PamAuthenticator verifica contra PAM (/etc/pam.d/carmen); MockAuthenticator
con credenciales en memoria para tests. AuthError grueso: BadCredentials
vs AccountUnavailable, sin filtrar existencia de cuentas. resolve_user
vía getpwnam. data/carmen como servicio PAM; ejemplo auth-probe.

11 tests; el camino PAM real se ejercita.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-21 17:47:05 +00:00
parent af3be482a9
commit 8a15b812f9
10 changed files with 572 additions and 2 deletions
+23
View File
@@ -2,6 +2,29 @@
Contratos canónicos + routing entre módulos. Antes: `core/brahman-*` + `shared/brahman-*`.
### feat(brahman-auth): autenticación del escritorio — contrato + PAM + mock
Crate nuevo `crates/protocol/brahman-auth`: la base del DM/greeter de
carmen (mirada). Contrato `Authenticator` agnóstico del backend:
`authenticate(usuario, secreto) -> UserInfo`, donde `UserInfo` lleva
`uid/gid/home/shell` — lo que el compositor necesita para arrancar la
sesión.
- **`PamAuthenticator`** — verifica contra PAM (`/etc/pam.d/<servicio>`,
por defecto `carmen`), el mismo subsistema de `login`/`sudo`. Un handle
PAM nuevo por intento; `authenticate()` cubre credenciales + estado de
la cuenta. `map_pam_error` traduce los `PamReturnCode` a la taxonomía
gruesa de `AuthError`.
- **`MockAuthenticator`** — credenciales fijas en memoria, para tests y
para iterar el greeter en cajas sin PAM.
- `AuthError` deliberadamente grueso: `BadCredentials` (reintentar) vs
`AccountUnavailable` (cuenta vetada); usuario inexistente y contraseña
errada dan el **mismo** error (no filtra existencia de cuentas).
- `resolve_user` vía `getpwnam` (nix). `UserInfo::synthetic` para dev.
- `data/carmen` — archivo de servicio PAM. Ejemplo `auth-probe` para
verificar PAM en una máquina real.
- 11 tests; el camino PAM real se ejercita (falla limpio sin servicio).
### feat(brahman-demo): bootstrap script reproducible — broker + producer + consumer + 4 explorers
Iter 22. Cierra el set de iteraciones de hoy: cualquier persona (o
future-me retomando el repo) puede levantar el escenario completo