Files
agents_and_robots/docs/security.md
T
egutierrez c5748212f8 chore: cerrar issue 0024c — security integration + docs
- Actualiza docs/security.md: nueva sección "Sistema de grupos centralizados"
  con estructura de los 3 YAML, acciones disponibles, campos deprecados
- Actualiza .claude/CLAUDE.md: añade security/ en la estructura del proyecto
- Mueve 0024 y 0024c a dev/issues/completed/
- Actualiza dev/issues/README.md: marca 0024, 0024a, 0024b, 0024c como completado

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

7.7 KiB

Seguridad — Protecciones contra prompt injection y abuso de tools

Este documento describe las capas de defensa implementadas para proteger los agentes Matrix contra ataques de prompt injection y abuso de herramientas.

Capas de defensa

La estrategia es defensa en profundidad: multiples capas independientes, ninguna es la unica barrera.

Mensaje del usuario
  |
  v
1. Input sanitization (pkg/sanitize/) — detecta patrones de injection
  |
  v
2. System prompt hardening — instrucciones anti-manipulation al LLM
  |
  v
3. Tool validation (deny-by-default) — cada tool valida sus inputs
  |
  v
4. Rate limiting (tools/registry.go) — limite de tool calls por room
  |
  v
5. RBAC (pkg/acl/) — control de acceso por usuario/rol

1. Sanitizacion de input (pkg/sanitize/)

Funciones puras que detectan patrones de prompt injection en mensajes entrantes.

Configuracion:

security:
  sanitize:
    enabled: true
    mode: warn          # warn | strip | reject
    min_severity: medium  # low | medium | high
    disabled_patterns: []  # nombres de patrones a ignorar

Modos:

  • warn: loguea warnings pero no modifica el mensaje (default)
  • strip: elimina las secciones sospechosas del mensaje
  • reject: rechaza el mensaje completamente con respuesta de error

Patrones detectados:

  • Delimitadores de sistema: <|system|>, <|assistant|>, [INST]
  • Frases de override: "ignore previous instructions", "you are now", etc.
  • Intentos de exfiltracion: "repeat your instructions", "show me your prompt"

Los patrones estan en pkg/sanitize/patterns.go. Son extensibles.

2. Hardening de system prompts

Todos los system prompts deben incluir una seccion de seguridad obligatoria. Template en .claude/templates/security-prompt.md.

Las instrucciones cubren:

  • Rechazo de acciones fuera del rol
  • Proteccion del system prompt (no revelar)
  • Rechazo de comandos destructivos
  • Validacion de coherencia contextual
  • Resistencia a redefinicion de identidad

3. Validacion en tools (deny-by-default)

Cada tool que hace I/O valida sus inputs de forma independiente.

tools/file/ — read_file

  • Deny-by-default: si AllowedPaths esta vacio, todo denegado
  • Path traversal: resuelve symlinks con filepath.EvalSymlinks, valida que el path este dentro de los permitidos
  • Prefix confusion: usa separador de directorio para evitar que /allowed/path matchee /allowed/pathevil

tools/ssh/ — ssh_command

  • AllowedCommands: allowlist de prefijos de comandos. Si esta definida, solo los comandos que matcheen se ejecutan
  • ForbiddenCommands: blocklist como segunda capa
  • Validacion de sintaxis: detecta pipes |, subshells $(), redirects >, chains &&/||/;
  • AllowedTargets: solo los hosts configurados

tools/http/ — http_get, http_post

  • AllowedDomains: solo los dominios configurados
  • SSRF protection: resuelve DNS y bloquea IPs privadas (127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), link-local (169.254.0.0/16) y metadata (169.254.169.254)

tools/matrix/ — matrix_send

  • AllowedRooms: si esta configurado, solo permite enviar a rooms especificos

4. Rate limiting

Limite de tool calls por room por minuto. Previene abuso repetitivo.

Configuracion:

security:
  tool_rate_limit:
    enabled: true
    max_calls_per_min: 10     # default 10
    cleanup_interval_s: 60    # limpieza de entries expiradas

Implementado en tools/ratelimit.go como sliding window per room. El registry verifica antes de ejecutar cada tool.

5. Aislamiento de filesystem

storage.base_path permite mover datos de runtime fuera del arbol del proyecto:

storage:
  base_path: /var/lib/agents/mi-bot  # o via $AGENTS_DATA_DIR

Prioridad: config base_path > $AGENTS_DATA_DIR/<id> > agents/<id>/data/ (default).

Esto previene que tools como read_file accedan accidentalmente a codigo fuente, .env, o configs del proyecto.

6. Aislamiento de claude -p (provider claude-code)

Cuando un agente usa el provider claude-code, el subproceso claude -p se ejecuta en un directorio de trabajo aislado, no en la raiz del repositorio.

Configuracion:

llm:
  primary:
    claude_code:
      working_dir: "/tmp/claude-agents/mi-bot"  # directorio aislado

Comportamiento:

  • Si working_dir esta configurado: se crea el directorio automaticamente con MkdirAll y se usa como CWD del subproceso
  • Si working_dir esta vacio: se crea un directorio temporal (os.MkdirTemp) y se loguea un WARN para que el operador lo note
  • Nunca se hereda el CWD del launcher (raiz del repo)

Esto evita que el subproceso claude -p tenga acceso de lectura/escritura al codigo fuente del proyecto, incluso con permission_mode: bypassPermissions.

Implementado en shell/llm/claudecode.goresolveWorkDir().

7. Sistema de grupos centralizados (security/)

Control de acceso centralizado: quien puede hablar con que agentes, y que puede hacer. Reemplaza los campos per-agente security.roles y matrix.filters.allowed_users (ahora deprecados).

Estructura de archivos

security/
  user-groups.yaml    # grupos de usuarios Matrix
  agent-groups.yaml   # grupos de agentes
  permissions.yaml    # politicas: que grupo de usuarios tiene que acciones en que agentes

user-groups.yaml

groups:
  admins:
    members: ["@admin:matrix-af2f3d.organic-machine.com"]
  developers:
    members: ["@dev1:homeserver.com", "@dev2:homeserver.com"]
  everyone:
    members: ["*"]  # wildcard: todos los usuarios

agent-groups.yaml

groups:
  all:
    agents: ["*"]   # wildcard: todos los agentes
  production:
    agents: ["assistant-bot", "asistente-2"]

permissions.yaml

policies:
  - agent_group: all         # aplica a todos los agentes
    permissions:
      - user_group: admins
        actions: ["*"]       # admins pueden hacer todo
      - user_group: everyone
        actions: ["ask"]     # todos pueden chatear
  - agent_group: production  # solo agentes de produccion
    permissions:
      - user_group: developers
        actions: ["ask", "command:deploy", "tool:ssh_command"]

Acciones disponibles

Accion Descripcion
* Todo permitido
ask Puede chatear con el agente (mensajes normales)
command:<name> Puede ejecutar el comando !<name>
tool:<name> El LLM puede llamar la tool <name> para este usuario

Resolucion de ACL

Al arrancar, el launcher:

  1. Carga todos los YAMLs con shellsecurity.Load("security/")
  2. Para cada agente, llama pksecurity.ResolveACL(agentID, policy)
  3. Inyecta la acl.ACL resultante en agents.New()

Comportamiento cuando la politica esta vacia: si security/ no existe o no hay politicas que apliquen al agente, la ACL esta vacia y el acceso es abierto (sin restricciones). Preferible a denegar todo por defecto en produccion.

Campos deprecados

Los siguientes campos en config.yaml del agente estan deprecated y no tienen efecto desde la activacion del sistema centralizado:

  • security.roles — reemplazado por security/permissions.yaml
  • matrix.filters.allowed_users — reemplazado por security/user-groups.yaml

Los campos siguen en el schema para compatibilidad con configs existentes y se eliminarán en un issue futuro.

Activacion

Para activar todas las protecciones, añadir al config.yaml del agente:

security:
  sanitize:
    enabled: true
    mode: warn
  tool_rate_limit:
    enabled: true
    max_calls_per_min: 10

Y asegurarse de que:

  • Las tools tienen allowlists configuradas (no vacias si se quieren usar)
  • El system prompt incluye la seccion de seguridad
  • storage.base_path apunta fuera del proyecto en produccion
  • claude_code.working_dir apunta fuera del repo si se usa el provider claude-code