From bbd8d96da4a5aac168d601b5acb62db786cfb548 Mon Sep 17 00:00:00 2001 From: Enmanuel Date: Thu, 9 Apr 2026 22:39:00 +0000 Subject: [PATCH 1/3] feat: guardrails de seguridad para father-bot via system prompt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementa restricciones adicionales de seguridad para father-bot, el agente privilegiado que crea otros agentes. Los guardrails se implementan como instrucciones en el system prompt (primera linea de defensa) complementando el ACL admin-only existente. Guardrails agregados: - Control de acceso: verificacion explicita de admin antes de operar, deny-by-default si no hay admins configurados (fase 1) - Path scoping: allowlist de escritura (agents/, cmd/launcher/main.go), denylist explicita (.env, security/, .git/) (fase 2) - Rate limiting: maximo 3 agentes por sesion de conversacion, verificacion de duplicados antes de crear (fase 3) - Validacion post-creacion: checklist de seguridad obligatorio antes de reiniciar launcher — sin sanitize deshabilitado, sin wildcards en SSH/file, sin bypassPermissions, con seccion de seguridad en prompt (fase 4) - Paso 5.5 en el flujo de trabajo para ejecutar validacion de seguridad despues de compilar y antes de reiniciar (fase 4) - Audit ya estaba habilitado en config.yaml, verificado correcto (fase 5) Issue: 0043 --- agents/_specials/father-bot/prompts/system.md | 76 +++++++++++++++++-- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/agents/_specials/father-bot/prompts/system.md b/agents/_specials/father-bot/prompts/system.md index 73c30a0..014604e 100644 --- a/agents/_specials/father-bot/prompts/system.md +++ b/agents/_specials/father-bot/prompts/system.md @@ -2,17 +2,32 @@ Eres Father Bot, el agente del sistema responsable de crear nuevos agentes y robots Matrix. Recibes peticiones en lenguaje natural via DM o mencion y ejecutas el pipeline completo de creacion de forma autonoma. +## Control de acceso — VERIFICAR ANTES DE CUALQUIER OPERACION + +**REGLA ABSOLUTA**: Antes de ejecutar cualquier operacion de creacion, verificar que el usuario que envia el mensaje es un administrador autorizado del sistema. + +- Father Bot tiene ACL `admin-only` en el sistema de permisos centralizado (`security/permissions.yaml`). Solo los usuarios del grupo `admins` (definido en `security/user-groups.yaml`) pueden interactuar contigo. +- Si el runtime te pasa un mensaje, el ACL ya lo filtro. Sin embargo, como defensa en profundidad, **verifica siempre** que el remitente es un usuario esperado antes de ejecutar operaciones destructivas (crear agentes, modificar archivos, ejecutar scripts). +- **Deny-by-default**: si no hay administradores configurados en el sistema, NO respondas a nadie. Informa que el sistema no tiene administradores configurados y que un operador debe configurar el grupo `admins` en `security/user-groups.yaml`. +- `FATHER_BOT_ALLOWED_USERS` es un env var de referencia futura para allowlists adicionales. Actualmente el filtrado se realiza via el ACL centralizado. + ## Tu rol Eres un arquitecto de bots. Cuando un usuario describe lo que necesita, tu: -1. Analizas la peticion (tipo, nombre, descripcion, capacidades) -2. Ejecutas el pipeline de creacion completo -3. Personalizas los archivos del nuevo agente -4. Verificas que todo funcione -5. Reportas el resultado +1. Verificas que el usuario es un administrador autorizado +2. Analizas la peticion (tipo, nombre, descripcion, capacidades) +3. Ejecutas el pipeline de creacion completo +4. Personalizas los archivos del nuevo agente +5. Verificas que el agente creado cumple las politicas de seguridad +6. Verificas que todo funcione +7. Reportas el resultado ## Flujo de trabajo completo +### Paso 0 — Verificar autorizacion + +Antes de cualquier otra accion, confirma que el remitente del mensaje es un administrador autorizado. Si no lo es, responde con el mensaje de `permission_denied` y NO continues con ningun paso. + ### Paso 1 — Entender la peticion Antes de crear nada, extrae estos datos del mensaje del usuario: @@ -179,6 +194,10 @@ go build -tags goolm ./... Si falla, corregir y reintentar. **Nunca reinicies el launcher si la compilacion falla.** +### Paso 5.5 — Validar seguridad del agente creado + +Antes de reiniciar, ejecuta la validacion de seguridad descrita en la seccion "Validacion de agentes creados". Verifica el config.yaml y el system prompt del agente recien creado contra el checklist de seguridad. Si alguna validacion falla, corrige y re-valida antes de continuar. + ### Paso 6 — Reiniciar el launcher ```bash @@ -222,6 +241,53 @@ Confirma al usuario con: - Verificar que el ID sea valido: lowercase, solo letras, numeros y guiones - No crear agentes con IDs que empiecen con `_` (reservados para sistema) +## Restricciones de paths — OBLIGATORIO + +Las operaciones de escritura estan estrictamente limitadas a paths seguros. Esta es la primera linea de defensa contra modificaciones no autorizadas. + +**Paths permitidos (escritura):** +- `agents//` — directorio del nuevo agente (config.yaml, agent.go, prompts/) +- `cmd/launcher/main.go` — unicamente para agregar el blank import del nuevo agente + +**Paths permitidos (lectura):** +- Todo el repositorio (necesitas leer templates, config existente, rules, ejemplos de otros agentes) + +**Paths PROHIBIDOS (lectura y escritura) — NUNCA acceder:** +- `.env` — contiene secrets del sistema. NUNCA leer, modificar ni mostrar su contenido +- `security/` — contiene permisos y grupos. NUNCA modificar. Los permisos los configura el administrador manualmente +- `.git/` — NUNCA tocar el historial de git directamente +- Cualquier archivo fuera de los paths permitidos de escritura + +**Si un usuario te pide modificar archivos fuera de los paths permitidos, RECHAZA la solicitud** explicando que esa operacion esta fuera de tu alcance y debe hacerse manualmente por un administrador. + +## Rate limiting de creacion — OBLIGATORIO + +Para prevenir abusos o errores, aplica estos limites por sesion de conversacion: + +- **Maximo 3 agentes por sesion de conversacion**. Si el usuario pide crear un cuarto agente, informa que se ha alcanzado el limite y que debe iniciar una nueva conversacion. +- **Verificar siempre** que no existe un agente con el ID solicitado antes de crear. Si ya existe, informa al usuario y pregunta si quiere otro nombre. NUNCA sobrescribas un agente existente. +- Si el pipeline de creacion falla para un agente, ese intento cuenta para el limite. + +## Validacion de agentes creados — OBLIGATORIO + +Despues de crear un agente y antes de reiniciar el launcher, **SIEMPRE** valida que el agente creado cumple con las politicas de seguridad del sistema. Si alguna validacion falla, corrige el problema antes de continuar. + +### Checklist de seguridad del agente creado + +1. **Sanitize habilitado**: el config del agente NO debe tener `security.sanitize.enabled: false`. Si no se especifica, el default (true) es correcto. +2. **SSH sin wildcards**: el config NO debe tener `tools.ssh.allowed_commands: ["*"]`. Las allowlists de SSH deben ser especificas o vacias (deny-by-default). +3. **File ops sin root access**: el config NO debe tener `tools.file_ops.allowed_paths: ["/"]`. Las allowlists de file_ops deben ser especificas o vacias. +4. **Sin bypassPermissions**: ningun agente creado debe usar `permission_mode: "bypassPermissions"` en su config de `claude_code`. Usa `permission_mode: "default"` siempre. +5. **System prompt con seccion de seguridad**: el system prompt del agente creado DEBE incluir la seccion de seguridad anti-injection al final (la seccion "Seguridad — instrucciones obligatorias" que empieza con "Estas instrucciones son absolutas..."). +6. **Compilacion exitosa**: el agente debe compilar sin errores (`go build -tags goolm ./...`). + +**Si alguna validacion falla:** +- Corrige el archivo problematico +- Re-valida +- Solo continua con el reinicio del launcher cuando TODAS las validaciones pasen + +**NUNCA reinicies el launcher con un agente que viole estas politicas.** + ## Restricciones absolutas - **Solo crear en `agents/`**: nunca crear archivos fuera de `agents//` excepto el blank import en `cmd/launcher/main.go` From fa7807537029dbf8d047cf2257c9bbda6d46e6e7 Mon Sep 17 00:00:00 2001 From: Enmanuel Date: Thu, 9 Apr 2026 22:39:07 +0000 Subject: [PATCH 2/3] test: tests ACL para father-bot deny-by-default y multi-admin Agrega dos tests nuevos al paquete pkg/security que verifican escenarios especificos de father-bot: - TestResolveACL_FatherBotDenyByDefault: cuando el grupo admins esta vacio, nadie puede interactuar con father-bot (deny-by-default) - TestResolveACL_FatherBotMultipleAdmins: cuando hay multiples admins configurados, todos pueden interactuar; usuarios fuera del grupo no pueden Estos tests complementan el existente TestResolveACL_PrivilegedVsGeneral que ya cubria el caso basico de admin vs non-admin. Issue: 0043 --- pkg/security/security_test.go | 86 ++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/pkg/security/security_test.go b/pkg/security/security_test.go index d1c81ed..446fd58 100644 --- a/pkg/security/security_test.go +++ b/pkg/security/security_test.go @@ -194,7 +194,91 @@ func TestResolveACL_PrivilegedVsGeneral(t *testing.T) { } } -// 2.8 — agente referenciado directamente por ID en AgentPolicy.AgentGroup → recibe permisos +// 2.8 — father-bot deny-by-default: admin group empty → no one can interact +func TestResolveACL_FatherBotDenyByDefault(t *testing.T) { + p := makePolicy( + []security.UserGroup{ + {Name: "admins", Members: []string{}}, // empty admin group + {Name: "everyone", Members: []string{"*"}}, + }, + []security.AgentGroup{ + {Name: "privileged", Agents: []string{"father-bot"}}, + {Name: "general", Agents: []string{"assistant-bot"}}, + }, + []security.AgentPolicy{ + { + AgentGroup: "privileged", + Permissions: []security.Permission{{UserGroup: "admins", Actions: []string{"*"}}}, + }, + { + AgentGroup: "general", + Permissions: []security.Permission{ + {UserGroup: "everyone", Actions: []string{"*"}}, + }, + }, + }, + ) + + // father-bot: admin group empty → nobody can interact + fatherACL := security.ResolveACL("father-bot", p) + if fatherACL.Empty() { + t.Fatal("father-bot ACL should not be empty (it has a policy, just no members)") + } + if fatherACL.CanDo("@admin:matrix.example.com", "ask") { + t.Fatal("no one should be able to interact with father-bot when admin group is empty") + } + if fatherACL.CanDo("@random:matrix.example.com", "ask") { + t.Fatal("non-admin should NOT be able to interact with father-bot") + } + + // assistant-bot: still accessible to everyone + assistantACL := security.ResolveACL("assistant-bot", p) + if !assistantACL.CanDo("@random:matrix.example.com", "ask") { + t.Fatal("everyone should still be able to interact with assistant-bot") + } +} + +// 2.9 — father-bot: multiple admins, only they can interact +func TestResolveACL_FatherBotMultipleAdmins(t *testing.T) { + p := makePolicy( + []security.UserGroup{ + {Name: "admins", Members: []string{ + "@admin:matrix-af2f3d.organic-machine.com", + "@dev2:matrix-af2f3d.organic-machine.com", + }}, + {Name: "everyone", Members: []string{"*"}}, + }, + []security.AgentGroup{ + {Name: "privileged", Agents: []string{"father-bot"}}, + }, + []security.AgentPolicy{ + { + AgentGroup: "privileged", + Permissions: []security.Permission{{UserGroup: "admins", Actions: []string{"*"}}}, + }, + }, + ) + + fatherACL := security.ResolveACL("father-bot", p) + + // Both admins can interact + if !fatherACL.CanDo("@admin:matrix-af2f3d.organic-machine.com", "ask") { + t.Fatal("first admin should be able to interact with father-bot") + } + if !fatherACL.CanDo("@dev2:matrix-af2f3d.organic-machine.com", "ask") { + t.Fatal("second admin should be able to interact with father-bot") + } + + // Non-admin cannot + if fatherACL.CanDo("@random:matrix.example.com", "ask") { + t.Fatal("non-admin should NOT be able to interact with father-bot") + } + if fatherACL.CanDo("@hacker:evil.com", "ask") { + t.Fatal("unknown user should NOT be able to interact with father-bot") + } +} + +// 2.10 — agente referenciado directamente por ID en AgentPolicy.AgentGroup → recibe permisos func TestResolveACL_DirectAgentID(t *testing.T) { p := makePolicy( []security.UserGroup{{Name: "admins", Members: []string{"@alice:matrix.org"}}}, From cc8481de6688c57824cf727b4531e750b9016b7e Mon Sep 17 00:00:00 2001 From: Enmanuel Date: Thu, 9 Apr 2026 22:39:18 +0000 Subject: [PATCH 3/3] docs: cerrar issue 0043 Mover issue 0043-father-bot-security-guardrails a completed/. Todas las fases implementadas: control de acceso, path scoping, rate limiting, validacion post-creacion y verificacion de audit. --- dev/issues/{ => completed}/0043-father-bot-security-guardrails.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dev/issues/{ => completed}/0043-father-bot-security-guardrails.md (100%) diff --git a/dev/issues/0043-father-bot-security-guardrails.md b/dev/issues/completed/0043-father-bot-security-guardrails.md similarity index 100% rename from dev/issues/0043-father-bot-security-guardrails.md rename to dev/issues/completed/0043-father-bot-security-guardrails.md