Skip to content

Soularr: plan de identidad para la UI — 20 octubre 2026

Avance del 22 de octubre: código central instalado, identidad pendiente

La lectura de las 13:04 CEST identificó el controlador central de CT212 como la versión e64bbba, sin el perfil soularr-auth-v1 preparado en fuente. A las 13:15:59 se actualizó únicamente /usr/local/bin/homelab-ctl al código exacto de main <REDACTED>, con copia privada durable de la versión anterior en el nodo y readback completo. Propietario, permisos 0755, boot, ancestros y filesystem local se comprobaron antes/después. No se ejecutó el controlador, install.sh o sync; no se leyeron tokens ni se cambiaron rutas, contenedores o servicios.

Este paso instala una capacidad opt-in; no activa autenticación. Siguen pendientes las identidades permitidas de Pocket ID, el cliente dedicado y su callback, la admisión de consumidores/ACL IPv4 e IPv6 y la transición del proxy con login real, conservando worker, datos y puertos previstos. La mera presencia del literal del perfil no demuestra su comportamiento desplegado.

PR158 también corrige una indicación peligrosa: sync --dry-run puede crear o actualizar caché local; no debe usarse como lectura pasiva aunque no despliegue rutas. La revisión del instalador incluyó ocho casos locales en Python 3.12/3.14: colisiones y sustitución de temporales, deriva, fallos de fsync y señales de cancelación. Recibo privado de instalación soularr-controller-code-install-dzh4bhx_/native.json, SHA a320fd37…. Una lectura independiente a las 13:17:55–57 confirmó código, metadatos y boot exactos, con FDs cerrados y cero ejecución del controlador; recibo soularr-controller-independent-code-326n54tz/native.json, SHA 7e995059…. Ninguna de estas lecturas acredita la activación del proxy.

Contexto de la propuesta del 20 de octubre

Propuesta sin cambios de configuración/runtime. Continúa el hallazgo LAN del 19 octubre, no es nuevo. Solo fuentes locales y upstream oficial; sin SSH, HTTP de producto, config privada, env, secretos, Vera, login o despertares. No se repitió el runtime conocido de las 18:26 del 20 octubre.

Conclusión y evidencia

Upstream no ofrece actualmente autenticación nativa y no se ha encontrado un adaptador OIDC reutilizable en las fuentes revisadas. No hay arreglo seguro de una variable: desactivar UI, cerrar 8265 o bind loopback rompería accesos. Se propone ensayar un proxy OIDC estándar delante del editor, conservando puerto, hostname y worker. No se instala un componente para completar esta auditoría.

Fuente Compose: ~/Dev/homelab-stacks, HEAD b1ae78c, limpio y sin AGENTS propio al revisar. ~/stacks no existe en este Mac. Propietario conocido: VM208 /home/monxas/stacks/media/compose.yaml.

Upstream oficial consultado el 20 octubre, commit <REDACTED>, del 6 octubre: AST de webui/webui.py solo contiene decoradores route, sin hook/middleware/import de identidad. GET/POST config y DELETE de importaciones siguen sin gate propio. run.sh ofrece WEBUI_ENABLED/WEBUI_PORT, sin variables de identidad. No se ejecutó código upstream ni descargó imagen nueva.

Revisión de Ansible del worktree container-monitor-errors-20261020, en especial roles/caddy_lxc, y fuentes de homelab-stacks (excluyendo env, config privada, appdata y dependencias): no aparecen despliegues OAuth2 Proxy, Authelia, Tinyauth o caddy-security. El rol describe plugins Cloudflare DNS y Sablier. El snippet WP-Pulse conserva una referencia histórica forward_auth Pocket ID; no es un adaptador válido. El mismo archivo y reference/cf-access.md explican que Pocket ID no ofrece /forward-auth. No reutilizar ese patrón ni inferir que está activo; este trabajo no modifica WP-Pulse.

Dependencias y consumidores encontrados en fuentes

Relación Consecuencia
Navegador → Caddy .40/.41/VIP → VM208:8265 Conservar hostname, TLS y ambos proxies
Navegador LAN → VM208:8265 El puerto también debe conducir al gate
WAN → Cloudflare Access → Caddy Mantener Access; no cubre LAN
Worker → Lidarr/slskd depends_on en Compose; preservar red media, credenciales y pipeline
Datos Conservar /home/monxas/appdata/soularr:/data y /mnt/nfs_media/downloads/soulseek:/downloads, RW actuales
Calendario SCRIPT_INTERVAL=1800; no convertir worker a lazy ni añadir cron

En fuentes tracked de homelab-stacks, 8265 aparece solo en media/compose.yaml y reverse-proxy/managed.caddy. No apareció otro consumidor entrante automatizado en las fuentes de infraestructura revisadas. No acredita todos los clientes: marcadores/dispositivos y tareas sin versionar siguen pendientes. El worker consulta Lidarr/slskd; eso no exige que estos llamen a su UI.

Opción concreta para intervención posterior

OAuth2 Proxy como reverse proxy completo evita modificar el binario Caddy o inventar autenticación en Flask. Referencias oficiales: OIDC y configuración. No se selecciona tag mutable ni se generan secretos en este plan. Al introducir una dependencia, seguir la guía existente de altas, no un instalador paralelo.

  1. Inventariar consumidores humanos/automatismos de puerto, hostname y rutas; reconciliar fuente desplegada con Compose local y conservar hashes/rollback. No solicitar GET config para descubrir clientes.
  2. Preparar candidato aislado con versión/digest fijado y contrato. Medir RAM/CPU; dependencias nuevas: Pocket ID, DNS y TLS para discovery/callback. Caída del proxy/IdP bloquea UI sin parar worker. El candidato inicial puede usar cookies cifradas, sin DB/Redis nuevo.
  3. Cliente OIDC exclusivo, callback exacta https://soularr.monxas.casa/oauth2/callback, identidades autorizadas explícitas, sin comodín de email. Secretos en almacenes privados existentes. Comprobar issuer/audience/nonce/state y PKCE S256 con la versión elegida. Cookies Secure, HttpOnly y host-only; no transmitir tokens del IdP al backend sin necesidad.
  4. Mantener host:8265, publicado por el proxy. Retirar solo publicación host de Soularr; backend sigue en red media para Lidarr/slskd. Proxy alcanza http://soularr:8265 por una red acotada, sin mounts de datos/socket Docker. Preservar imagen Soularr, mounts y SCRIPT_INTERVAL. La red media continúa siendo límite de confianza: no pretende aislar otro contenedor comprometido.
  5. Mover tunnel.hostname del backend al proxy: un dueño de ruta. Declarar puerto interno/publicado del proxy según renderer; no copiar 8265 como puerto interno si escucha en 4180. Caddy puede conservar upstream host .208:8265, ahora con gate. Preparar render/diff sin editar managed.caddy generado ni ejecutar sync como inspección. Ambas fuentes deben converger sin alterar rutas ajenas.
  6. Entrada por IP conduce al hostname TLS; probar Host arbitrario, redirección abierta y cabeceras falsas. Proteger static, /stream, config y métodos mutadores por el mismo gate; no crear bypass por comodidad. Cerrar solo el puerto o autenticar solo Caddy dejaría otras rutas de elusión.
  7. Fixture aislada sin credenciales/descargas: GET/POST/DELETE ficticios y SSE. Probar anónimo, autorizado/no autorizado, cookie inválida, CSRF, callback adulterado, cabeceras falsificadas y bypass LAN/IPv6; reconexión stream y UI. Si proxy/app no cubren CSRF/Origin necesarios en la versión elegida, resolver mediante mecanismos estándar antes de desplegar, no inferir cobertura de OIDC.
  8. Solo tras revisar candidato: transición de puerto/labels sin backend público, recreación acotada conservando datos/imagen/políticas, ambos Caddy/VIP/edge y acceso humano real. No provocar descargas como prueba. Rollback comprende Compose, proxy, labels y cliente; volver al previo restaura la UI LAN sin gate.

Cierre y límites

UI accesible con identidad LAN/WAN y sin bypass host:8265; usuario no autorizado no obtiene config/logs ni cambia importaciones; pipeline/datos previos intactos. Reutilizar service_contracts/service_routes, sin cron ni plataforma nueva de observación. Login personal permanece pendiente hasta probarlo realmente.

Se ha preparado un candidato inactivo con configuración y fixture local. OAuth2 Proxy y Caddy oficiales prueban OIDC sintético firmado, PKCE/nonce, allowlist, Origin y SSE de dos eventos. No son pruebas de productos reales. El candidato sigue bloqueado para despliegue por clientes desconocidos, integración única de renderer/ACL, recursos y validación de Pocket ID pendientes.

20-10-2026: integración del perfil en fuente, sin despliegue

Se prepara tunnel.access_profile=soularr-auth-v1 en el renderer central services/homelab-ctl/homelab-ctl.py. La fuente de instalación services/homelab-ctl/install.sh copia ese fichero a /usr/local/bin/homelab-ctl en CT212; el README del componente documenta que VM208 quedó con control local y reenvía las operaciones de rutas al controlador central. Esto acredita el propietario en fuente; no demuestra que el runtime CT212 contenga este cambio. No se modifica scripts/homelab-ctl.py ni se ejecuta el instalador.

El perfil admite únicamente Soularr, VM208:8265 y no lazy; genera el mismo handle del candidato con Origin exacto para POST/PUT/PATCH/DELETE y eliminación explícita de las cinco cabeceras documentadas. Perfil vacío/desconocido, propietario/destino inválido, ruta static con perfil y duplicados del hostname protegido bloquean la generación antes de escritura, sin elegir un dueño por orden. La proyección de inventario/cache conserva la etiqueta; las rutas sin perfil mantienen sus bytes. No se introduce un mecanismo genérico de snippets.

Pruebas locales aisladas cubren esos contratos y comparan el bloque con el candidato. El binario oficial Caddy2.11.7 ya disponible adapta el resultado y se comprueban sus matchers/orden/headers JSON; esto es parseo offline, no prueba de peticiones ni validación del plugin/runtime de los dos Caddy. El workflow existente service-contract-tests amplía sus paths y ejecuta los tests del renderer central en Python3.10/3.12, antes fuera de sus dos directorios discover.

Sigue inactivo: no se cambian labels/Compose/firewall, cliente Pocket ID, credenciales ni recursos. Antes de desplegar siguen siendo necesarias la reconciliación y aplicación coordinada del overlay preparado, ACL IPv4/IPv6 sin bypass, inventario de consumidores directos, configuración privada/identidades elegidas, permisos del UID y validaciones reales de login y presupuesto N1. El gate OIDC no sustituye al gate Origin de la aplicación.

20-10-2026: transición Compose preparada, todavía inactiva

El overlay candidato ya conserva worker, imagen, intervalo1800, mounts y dependencias media, y traslada el único puerto host8265 y hostname al proxy interno4180 con perfil soularr-auth-v1. Cinco pruebas estructurales pasan con cada CLI local Compose v2.35.1-desktop.1 y5.5.1, incluido el merge de la fuente local sin modificarla ni copiarla. El recibo de validación registra alcance y límites; no acredita Compose desplegado ni acceso real.

El overlay no participa en la configuración activa. Su perfil sólo controla el proxy: combinar el archivo ya elimina puertos/labels del worker, y solicitar explícitamente el proxy puede arrancarlo sin activar antes el perfil. No se incluye ni se ha ejecutado una orden de despliegue. La red interna nueva acota sus dos miembros, pero conservar la red media deja acceso directo al backend desde sus pares. Siguen pendientes clientes/automatismos, ACL y ese límite de confianza, Pocket ID, permisos, recuperación y recursos/N1. No se ha cambiado runtime, firewall, renderer instalado ni contratos activos.