diff --git a/app.md b/app.md index 967458d..ba35038 100644 --- a/app.md +++ b/app.md @@ -58,9 +58,10 @@ navegador (SPA Mantine) ▼ unibus_admin (gateway Go, identidad ADMIN del operador) ├── pkg/client (unibus) → CreateRoom / Invite / Kick / ListMyRooms (firma + cripto E2E) + ├── pkg/client (unibus) → ListUsers / AddUser / RevokeUser (API admin firmada; funciona en cluster) ├── GET firmado → /rooms/{id}/members (CanonicalRequest + SignEd25519, reusa la construcción del bus) ├── GET /healthz (CA-pinned)→ estado + posture de los 3 nodos del cluster - └── membership.Store (opc.) → users (allowlist) cuando hay acceso directo al store + └── membership.Store (opc.) → users (allowlist) como fallback single-node con --db ▼ cluster unibus (magnus + homer + datardos, enforce + ACL + TLS + KV) ``` @@ -77,7 +78,7 @@ no expone. Nunca reimplementa firma ni cripto. |---|---|---| | **Cluster** | up/down + posture (enforce/acl/tls/cluster/store) + latencia de cada nodo | `GET /healthz` (auth-exempt) de los nodos en `--nodes`, TLS pin a la CA del bus | | **Rooms** | listar (rooms del admin), crear (subject + E2E/persist/firmado), ver miembros, invitar, expulsar+rekey | `pkg/client` (mutaciones) + GET firmado (miembros) | -| **Users** | listar/añadir/revocar la allowlist del bus | `membership.Store` directo — sólo con `--db` (single-node) o acceso KV admin | +| **Users** | listar/añadir/revocar la allowlist del bus | `pkg/client` (`ListUsers`/`AddUser`/`RevokeUser`) contra la API admin-only del plano de control, firmando como el operador. Funciona en cluster (los nodos escriben al mismo store que las rooms) sin acceso directo al store. `--db` queda como fallback single-node opcional | ## Cómo arrancar @@ -85,13 +86,14 @@ no expone. Nunca reimplementa firma ni cripto. # Mock (iterar la SPA sin bus): ./unibus_admin --mock --port 8480 -# Real contra un membershipd local (dev, sqlite, sin TLS): +# Real contra un membershipd local (dev, sin TLS). Users vía la API del plano de +# control; añade --db sólo si quieres gestionar users contra un SQLite local: ./unibus_admin --port 8480 \ --ctrl-url http://127.0.0.1:8470 --nats-url nats://127.0.0.1:4250 \ - --db ./local_files/unibus.db \ --identity-pass unibus/operator-identity -# Producción (cluster magnus, enforce + TLS + nkey): +# Producción (cluster magnus, enforce + TLS + nkey). Sin --db: la pestaña Users +# gestiona la allowlist por la API admin firmada del plano de control: ./unibus_admin --port 8480 --bind 127.0.0.1 \ --ctrl-url https://127.0.0.1:8470 --nats-url tls://127.0.0.1:4250 \ --ca /opt/unibus/tls/ca.crt \ @@ -127,11 +129,17 @@ ofuscado (`admin-.organic-machine.com`). Credenciales en `pass` ## Gaps conocidos -- **Users en el cluster (KV)**: el plano de control no expone endpoint HTTP de users - — viven sólo en el store. Con el cluster en `--store kv`, el gateway no abre el KV - todavía, así que la pestaña Users queda degradada (estado informativo). Se habilita - con la vía de alta KV que añade la rama `quick/0011-deploy-gaps` del repo unibus, o - con `--db` en single-node. +- **Users contra el cluster desplegado**: el código del plano de control (unibus + master, v0.10.0) ya expone la API admin-only de users (`GET/POST /users`, + `POST /users/{signpub}/revoke`) y el gateway la consume firmando como el operador. + La cadena completa (list/add/revoke + idempotencia 409) está verificada end-to-end + contra un `membershipd` master local. El gap restante es de **despliegue**: los + binarios `membershipd` que corren hoy en el cluster (magnus/homer/datardos) son + anteriores al merge de esta ruta y devuelven `404` en `/users`, así que la pestaña + Users sólo será funcional en producción cuando el bus se actualice a v0.10.0. El + gateway ya conecta y firma correctamente contra esos nodos (verificado: `/api/me` + responde con el endpoint real del operador y pasa el `enforce` de magnus). Para + gestión single-node sin esperar al cluster, `--db` sigue disponible. - **meta-leader / tamaño de quórum** del cluster: `/healthz` no los expone; requieren el endpoint de monitoreo de NATS (varz/jsz). La pestaña Cluster muestra up/posture. - **Invite a room E2E**: requiere las claves públicas (sign_pub + kex_pub) del