0102afa06e
Mueve el issue a completed/ y actualiza el índice. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.6 KiB
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/yshell/security/ya existen (0024a, 0024b).agents/runtime.goya tiene un campoacl acl.ACL(añadido en issue 0010). Verificar siagents.New()lo acepta como parámetro o si necesita extenderse.shell/matrix/listener.gotiene checks deAllowedUsersque se eliminan (el ACL del runtime los reemplaza).internal/config/schema.gotienesecurity.roles(lines ~290-315) ymatrix.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 enAgent{}agents/runtime.go— composición: recibeacl.ACLpre-resuelta
Tareas
Fase 1: Migrar permisos existentes
- 1.1 Leer los bloques
security.rolesdeagents/assistant-bot/config.yamlyagents/asistente-2/config.yamly migrarlos asecurity/permissions.yaml - 1.2 Leer
matrix.filters.allowed_usersde ambos configs y añadir esos usuarios a los grupos correspondientes ensecurity/user-groups.yaml - 1.3 Verificar que
security/permissions.yamlcaptura 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ñadirshellsecurity.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, llamarsecurity.ResolveACL(cfg.Agent.ID, policy)y pasar laacl.ACLresultante aagents.New(). Loguear a nivel DEBUG cuántos roles se resolvieron para el agente. - 2.3 En
agents/runtime.go: verificar/añadir queagents.New()aceptaacl.ACLcomo parámetro. Si ya existe el campoaclenAgent{}, adaptar la firma deNew(). Si no existe, añadir campo y lógica deCanDo()enshouldHandle(). - 2.4 En
agents/runtime.go: cuandoa.acl.Empty()es true (policy vacía), el comportamiento es "sin restricciones" (igual que antes). Cuando no está vacía,shouldHandle()verificaa.acl.CanDo(senderID, "ask")para mensajes ya.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 deAllowedUsersenshouldHandle()(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 enAllowedUsers(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 insteadsobre el camposecurity.rolesy sobrematrix.filters.allowed_users. No eliminar el campo (backward compat temporal). - 3.4 En
agents/assistant-bot/config.yaml: eliminar bloquesecurity.rolesy campoallowed_users - 3.5 En
agents/asistente-2/config.yaml: eliminar bloquesecurity.rolesy campoallowed_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
adminspuede 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. Marcarsecurity.rolesyallowed_userscomo deprecated. - 6.2 Actualizar
CLAUDE.md: añadirsecurity/en la sección de estructura del proyecto - 6.3 Cerrar issue 0024: mover
dev/issues/0024-centralized-security-groups.mdy sub-issues adev/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.rolesyallowed_userspermanecen 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.