Agent-Hellboy / Agent-Hellboy/mcp-runtime

feat(ui): shared session store to allow UI/gateway horizontal scaling

Abierto
#257 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Go
Estrellas
6
Forks
1
Merge medio
11 h 33 min
PR fusionados (30 d)
13

Descripción

## Problem

`mcp-sentinel-ui` keeps browser sessions in an in-memory map (`uiSessionStore` in `services/ui/main.go`). Each pod has its own store, so with multiple UI replicas:

- `POST /auth/login` may hit pod A (session created)
- `GET /auth/status` or `/auth/admin-check` may hit pod B (session missing → `authenticated: false`)

The same applies when the gateway load-balances across multiple UI backends.

This broke Kind E2E `ui-auth` when `k8s/09-ui.yaml` and `k8s/10-gateway.yaml` were scaled to 3 replicas ([#256](https://github.com/Agent-Hellboy/mcp-runtime/pull/256)). We reverted both to **`replicas: 1`** as a short-term fix.

## Current behavior

- Session cookie: `mcp_ui_session` (opaque ID, not the raw API key)
- Store: in-process map, cleared on UI pod restart
- Affected paths: `/auth/login`, `/auth/logout`, `/auth/status`, `/auth/admin-check` (Grafana forwardAuth), API proxy auth injection

## Goal

Allow `mcp-sentinel-ui` (and gateway) to run with **>1 replica** without breaking login, admin Grafana access, or gateway auth flows.

## Options to evaluate

1. **Postgres-backed sessions** — platform already runs `mcp-sentinel-postgres` and `platformstore` for identity; add a `ui_sessions` table or reuse platform JWT/session primitives where possible.
2. **Signed/stateless session tokens** — store principal + expiry in a signed cookie/JWT validated by any UI pod (no server-side lookup except revocation).
3. **Redis (or similar)** — only if we want a dedicated ephemeral cache; adds a new dependency not currently in the stack.

Prefer aligning with existing platform auth (`PLATFORM_JWT_SECRET`, `platformstore`) over introducing Redis unless there is a clear latency/ops reason.

## Acceptance criteria

- [ ] Multiple UI replicas: login → status → logout works through direct UI and gateway paths
- [ ] `/auth/admin-check` works for admin sessions across replicas (Grafana ingress)
- [ ] E2E `ui-auth` scenario passes with UI/gateway replicas > 1
- [ ] Document rollout/restart behavior (session persistence vs forced re-login)
- [ ] Update `k8s/09-ui.yaml` / `k8s/10-gateway.yaml` replica counts once safe

## References

- `services/ui/main.go` — `uiSessionStore`, `handleLogin`, `handleStatus`, `handleAdminCheck`
- `services/ui/main_test.go` — restart clears sessions test
- `test/e2e/ui_auth_flows.py` — gateway vs direct UI auth checks
- Kind E2E failure: https://github.com/Agent-Hellboy/mcp-runtime/actions/runs/26418823337/job/77769727661

## Interim constraint

Keep **`replicas: 1`** for `mcp-sentinel-ui` and `mcp-sentinel-gateway` until this is implemented.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.