Files
agents_and_robots/dev/issues/0024c-security-integration.md
T
egutierrez 0102afa06e chore: cerrar issue 0024b-security-loader
Mueve el issue a completed/ y actualiza el índice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 20:32:23 +00:00

6.6 KiB

0024c — Security integration: wiring, cleanup config, docs

Parte c del issue 0024-centralized-security-groups.md. Requiere 0024a y 0024b completados.

Objetivo

Conectar el sistema centralizado de seguridad al launcher y al runtime. Eliminar los controles per-agente (security.roles, matrix.filters.allowed_users) de los configs de agente. Activar el feature flag. Actualizar docs.

Contexto

  • pkg/security/ y shell/security/ ya existen (0024a, 0024b).
  • agents/runtime.go ya tiene un campo acl acl.ACL (añadido en issue 0010). Verificar si agents.New() lo acepta como parámetro o si necesita extenderse.
  • shell/matrix/listener.go tiene checks de AllowedUsers que se eliminan (el ACL del runtime los reemplaza).
  • internal/config/schema.go tiene security.roles (lines ~290-315) y matrix.filters.allowed_users (line ~230) que se deprecan.

Arquitectura

cmd/launcher/main.go                     MODIFIED
agents/runtime.go                        MODIFIED
shell/matrix/listener.go                 MODIFIED
internal/config/schema.go                MODIFIED
agents/assistant-bot/config.yaml         MODIFIED
agents/asistente-2/config.yaml           MODIFIED
dev/feature_flags.json                   MODIFIED
docs/security.md                         MODIFIED
CLAUDE.md                                MODIFIED

Patron pure core / impure shell

  • cmd/launcher/impuro: carga la policy, resuelve ACL, inyecta en Agent{}
  • agents/runtime.gocomposición: recibe acl.ACL pre-resuelta

Tareas

Fase 1: Migrar permisos existentes

  • 1.1 Leer los bloques security.roles de agents/assistant-bot/config.yaml y agents/asistente-2/config.yaml y migrarlos a security/permissions.yaml
  • 1.2 Leer matrix.filters.allowed_users de ambos configs y añadir esos usuarios a los grupos correspondientes en security/user-groups.yaml
  • 1.3 Verificar que security/permissions.yaml captura todos los permisos existentes antes de eliminar los bloques per-agente

Fase 2: Wiring en launcher y runtime

  • 2.1 En cmd/launcher/main.go: añadir shellsecurity.Load("security/") al inicio del proceso de arranque. Si devuelve error, loguear WARN y continuar con policy vacía (no fail-fast — comportamiento conservador)
  • 2.2 En cmd/launcher/main.go: para cada agente, llamar security.ResolveACL(cfg.Agent.ID, policy) y pasar la acl.ACL resultante a agents.New(). Loguear a nivel DEBUG cuántos roles se resolvieron para el agente.
  • 2.3 En agents/runtime.go: verificar/añadir que agents.New() acepta acl.ACL como parámetro. Si ya existe el campo acl en Agent{}, adaptar la firma de New(). Si no existe, añadir campo y lógica de CanDo() en shouldHandle().
  • 2.4 En agents/runtime.go: cuando a.acl.Empty() es true (policy vacía), el comportamiento es "sin restricciones" (igual que antes). Cuando no está vacía, shouldHandle() verifica a.acl.CanDo(senderID, "ask") para mensajes y a.acl.CanDo(senderID, "command:"+cmd) para comandos.

Fase 3: Limpiar listener y config

  • 3.1 En shell/matrix/listener.go: eliminar el bloque de chequeo de AllowedUsers en shouldHandle() (líneas ~285-301). El control de acceso ahora lo hace el runtime.
  • 3.2 En shell/matrix/listener.go: eliminar el invite gating basado en AllowedUsers (líneas ~105-119). Las invitaciones se aceptan siempre; el ACL se aplica cuando el usuario habla.
  • 3.3 En internal/config/schema.go: añadir comentario // Deprecated: use security/ centralized groups instead sobre el campo security.roles y sobre matrix.filters.allowed_users. No eliminar el campo (backward compat temporal).
  • 3.4 En agents/assistant-bot/config.yaml: eliminar bloque security.roles y campo allowed_users
  • 3.5 En agents/asistente-2/config.yaml: eliminar bloque security.roles y campo allowed_users

Fase 4: Activar feature flag

  • 4.1 En dev/feature_flags.json: añadir entrada:
    "centralized-security-groups": {
      "enabled": true,
      "issue": "0024",
      "description": "Sistema centralizado de grupos de usuarios y agentes para control de acceso",
      "added": "2026-03-08"
    }
    

Fase 5: Tests

  • 5.1 go build -tags goolm ./... compila sin errores
  • 5.2 go test -tags goolm ./... pasa completo
  • 5.3 Arrancar el launcher localmente y verificar en logs: "security policy loaded", "resolved ACL for agent" a nivel DEBUG/INFO
  • 5.4 Verificar que un usuario listado en admins puede ejecutar comandos y tools
  • 5.5 Verificar que un usuario no listado solo puede hacer ask (si la policy lo define así)

Fase 6: Docs y cleanup

  • 6.1 Actualizar docs/security.md: añadir sección "Sistema de grupos centralizados" con estructura de los 3 YAML, campos disponibles, ejemplos, y cómo se resuelven las ACLs. Marcar security.roles y allowed_users como deprecated.
  • 6.2 Actualizar CLAUDE.md: añadir security/ en la sección de estructura del proyecto
  • 6.3 Cerrar issue 0024: mover dev/issues/0024-centralized-security-groups.md y sub-issues a dev/issues/completed/

Ejemplo de uso

Flujo completo en producción:

1. Editar security/user-groups.yaml — añadir @newuser al grupo "developers"
2. Reiniciar launcher (o esperar hot-reload si aplica)
3. @newuser puede hablar con todos los agentes según los permisos del grupo "developers"
   Sin tocar ningún config.yaml de agente individual.

Decisiones de diseño

  • No fail-fast en loader: si security/ no existe o hay error de parseo, el launcher arranca con ACL vacía (sin restricciones). Preferible a que todos los agentes fallen por un typo en YAML. Se loguea WARN visible.
  • Eliminar invite gating: el listener ya no filtra invites por AllowedUsers. El control ocurre cuando el usuario intenta interactuar. Más simple y consistente.
  • Deprecated pero no eliminado del schema: los campos security.roles y allowed_users permanecen en el schema para no romper configs externos. Se eliminarán en un issue de limpieza posterior (0025 o similar).

Prerequisitos

  • 0024a completado
  • 0024b completado

Riesgos

  • Agentes sin permisos si security/permissions.yaml está vacío: si se eliminan los bloques per-agente antes de migrar a permissions.yaml, los agentes quedan abiertos a todos. Mitigación: hacer la migración (tarea 1.1-1.3) ANTES de eliminar los bloques (tarea 3.4-3.5).
  • Firma de agents.New() cambia: puede requerir actualizar tests existentes del runtime. Verificar antes.