Descripción
Sesión s109 (2026-06-05): auditoría de profundidad sobre la sub-área 3 del dominio monitoring — los servicios de IA del CNS (CreaRack Network Sentinel): proveedores LLM, síntesis de insights/explicaciones, feedback loop de aprendizaje, Tutor de redes y el servicio de notificaciones.
Alcance auditado: ~2.900 LOC (monitoring/services/ai_providers/*, insight_service.py, explain_service.py, pattern_service.py, tutor_service.py, cns_feedback_loop.py, notification_service.py).
Motor: workflow auditoria-suprema-monitoring-sa3 — 4 finders por slice (ia-providers · insights · cns-tutor · notification) → dedup por grupos de índices → verificación adversarial escalonada (ALTA 3 lentes / MEDIA 2 / BAJA 1).
Resultado: 33 crudos → 26 dedup → 23 confirmados (4 ALTA / 11 MEDIA / 8 BAJA), 3 refutados. Todos arreglados en una tanda (Regla 22, PR #68) explotando 7 raíces comunes.
Recuperación tras cuelgue: el workflow había completado y guardado
monitoring-sa3.json; el resultado se recuperó del transcript de la sesión colgada por script, sin re-correr la auditoría.
Los 4 ALTA
A1 · Fuga cross-tenant en el feedback loop (la gorda)
La cache global cns:learned_patterns mezclaba los patrones aprendidos de las conversaciones/revisiones de los operadores de todas las organizaciones —incluyendo commands/rollback_commands— y los inyectaba en los insights de cualquier org vía StaticRulesProvider. Bypass del aislamiento RLS en la capa de patrones.
Fix: cache particionada por org (cns:learned_patterns:{org_id}); extract_learned_patterns(org_id) exige org y filtra todas las queries; refresh_learned_patterns() itera las orgs; el org_id del target se propaga al provider vía device_context.
A2 · Prompt injection sin sanitizar
El input de usuario/dispositivo (nombres, logs SSH, trigger de anomalía, conversaciones) se concatenaba directo al prompt LLM.
Fix: nuevo ai_providers/sanitize.py (paridad con el sanitizeChunk del Oráculo): redact_secrets (tapa contraseñas/API keys/community SNMP/PEM) + wrap_untrusted (encapsula los datos no confiables entre delimitadores <<<UNTRUSTED_DATA ...>>>). build_user_prompt centraliza el armado en los 4 providers; system prompt instruido a no obedecer directivas dentro de esos bloques.
A3 · Bug activo: el Tutor estaba roto
tutor_service importaba from .ai_guardrails import is_on_topic y el módulo no existía en disco (ImportError latente desde v1.0.33 → el endpoint Tutor reventaba al primer uso).
Fix: creado ai_guardrails.py con is_on_topic (pre-filtro ~130 términos de networking, accent-insensitive) + test de import en CI para que un módulo fantasma no vuelva a pasar el merge.
A4 · SSRF en webhooks de notificación
validate_webhook_url era una copia desincronizada de net_guard (no bloqueaba el overlay NetBird 100.64.0.0/10 ni 0.0.0.0/8, crasheaba con puerto malformado).
Fix: delega en el guard compartido net_guard.validate_destination_url (única fuente de verdad); headers allowlisted + rechazo CRLF; rate limit real por tenant; payload minimal opcional.
MEDIA / BAJA — por raíz
- Cost/rate guard IA (
ai_cost_guard.py, atómicocache.add+incr) en explain/revise/tutor — antes explain/revise no tenían tope (DoS de coste); el del Tutor tenía una race. (M5/B21) - Validación de input en Explain:
max_length+is_on_topic. (M8) - Hooks de insight agrupados en un único
sync_to_async; niveles de log subidos en los críticos. (M9/M10) parse_llm_jsoncompartido enbase.py+ dispatcher único enexplain_service. (M6/B19)- Historial del Tutor cacheado por org. (M11)
- Limpieza: constantes renombradas, cap de corpus por org, model Gemini legacy centralizado + marcado dead-code. (B16/B17/B20)
Verificación
tests/api/test_monitoring_sa3.py (+18 tests): import del Tutor, redacción/encapsulado anti-injection, aislamiento por org de patrones/historial, SSRF + allowlist de headers, rate guard atómico. Suite verde (18 nuevos + 51 monitoring), ruff limpio, sin migraciones.
Deuda anotada (backlog Etapa 3)
- M15 — pin de IP anti-DNS-rebinding en webhooks/probes (centralizado en
net_guard, compartido con http_service). - B18 —
auto_resolveclasifica insights por substring; migrar a un campo estructuradocategory(requiere migración + backfill).
Referencias
- Datos completos:
public/supercontext/auditoria-suprema/monitoring-sa3.{md,json}+ doc maestroAUDITORIA_SUPREMA.md§8e. monitoring: 4 de 6 sub-áreas cerradas (sa1, sa2, sa3, sa6). Pendientes: sa4 (ITSM/alerting), sa5 (wireless+UPS).
Véase también
- [[feature—monitoring—auditoria-suprema-sa6-observatory-realtime]]
- [[concept—saas—multi-tenancy]]
- [[concept—security—prompt-injection]]
- [[entity—monitoring—service—net-guard]]
Referenciado desde
- _get_org_from_request: autenticación única del CNS (sesión + Agente) tras B-01/B-11
- Auditoría Suprema 2 · Cola config-ia: IA del workspace, drivers CNS y saneado de prompts
- Auditoría Suprema 2 · Tanda 1 (monitoring + racks): gates de permiso en Observatory, CNS y radar de integridad
- Cola de auditoría B (task #286): CNS e insights de IA — WS sin gate de permiso, apply/rollback sin Agente, prompts sin sanear
- Ordenamiento por fecha en tabla CNS (v1.61.4)