# Aegis v2 — Plan de Tareas: Sistema de Tests de Validación Red Team / Blue Team > **Instrucciones de uso**: Cada tarea (T-XXX) es una unidad de trabajo independiente que debe > resultar en un commit. Están ordenadas secuencialmente — cada tarea puede depender de las > anteriores pero nunca de las posteriores. Cada tarea incluye una sección de validación: > no hagas commit hasta que todos los checks pasen. > > **Contexto**: Este plan extiende el MVP de Aegis (36 tareas completadas) para implementar > un sistema completo de validación de tests de seguridad inspirado en [Validato](https://validato.io/). > La idea central: cada TTP de MITRE ATT&CK tiene tests que son ejecutados por el Red Team > y validados/detectados por el Blue Team. Cada test tiene pestañas separadas para evidencias > de ataque (Red Team) y detección (Blue Team), con un flujo de validación por managers de > ambos equipos que actualiza progresivamente el estado del test y de la TTP. --- ## Visión General del Flujo de Validación ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ CICLO DE VIDA DE UN TEST │ │ │ │ ┌──────┐ ┌──────────────┐ ┌─────────────────┐ ┌───────────┐ │ │ │ DRAFT│───▶│RED_EXECUTING │───▶│ BLUE_EVALUATING │───▶│ IN_REVIEW │ │ │ └──────┘ └──────────────┘ └─────────────────┘ └───────────┘ │ │ │ │ │ ┌────────────────────┤ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │ REJECTED │ │VALIDATED │ │ │ └──────────┘ └──────────┘ │ │ │ │ │ └──────▶ Vuelve a DRAFT │ └─────────────────────────────────────────────────────────────────────────┘ Estados del Test: - draft: Creado, pendiente de ejecución por Red Team - red_executing: Red Team documenta ataque y sube evidencias - blue_evaluating: Blue Team documenta detección y sube evidencias - in_review: Ambos managers revisan evidencias - validated: Aprobado por ambos managers - rejected: Rechazado — vuelve a draft para rehacer Roles involucrados: - red_tech: Crea tests, documenta ataques, sube evidencias de ataque - blue_tech: Documenta detección, sube evidencias de detección - red_lead: Valida/rechaza la parte de Red Team - blue_lead: Valida/rechaza la parte de Blue Team - admin: Acceso total ``` --- ## Catálogo de Tests Básicos por TTP Los tests básicos se obtienen de varias fuentes: 1. **Atomic Red Team** (Red Canary): repositorio open-source con tests atómicos mapeados a MITRE ATT&CK 2. **MITRE ATT&CK procedures**: procedimientos documentados en la propia base de datos de MITRE 3. **Tests personalizados**: creados manualmente por los equipos según su entorno --- ## FASE 10 — Evolución del Modelo de Datos para Red/Blue Team ### T-100: Ampliar estados del Test (TestState) **Objetivo:** Añadir los nuevos estados al ciclo de vida del test que permitan diferenciar las fases de Red Team ejecutando, Blue Team evaluando, y revisión por managers. **Archivos a modificar:** - `backend/app/models/enums.py` **Cambios en `TestState`:** ```python class TestState(str, enum.Enum): draft = "draft" red_executing = "red_executing" # NUEVO: Red Team documentando ataque blue_evaluating = "blue_evaluating" # NUEVO: Blue Team evaluando detección in_review = "in_review" validated = "validated" rejected = "rejected" ``` **Generar migración Alembic** para actualizar el enum en PostgreSQL. **Validación:** - [ ] `alembic upgrade head` aplica la migración sin errores - [ ] Los tests existentes con estados antiguos siguen funcionando - [ ] Se pueden crear tests con los nuevos estados vía SQL directo - [ ] `alembic downgrade -1` revierte sin errores --- ### T-101: Modelo EvidenceTeam — separar evidencias Red/Blue **Objetivo:** Añadir un campo `team` a las evidencias para distinguir si pertenecen al Red Team (evidencia de ataque) o al Blue Team (evidencia de detección). **Archivos a modificar:** - `backend/app/models/enums.py` — añadir enum `TeamSide` - `backend/app/models/evidence.py` — añadir campo `team` **Nuevo enum:** ```python class TeamSide(str, enum.Enum): red = "red" blue = "blue" ``` **Nuevo campo en Evidence:** | Campo | Tipo | Restricciones | |-----------|-------------------|----------------------------------| | team | Enum(TeamSide) | not null, default "red" | | notes | Text | nullable (notas sobre la evidencia) | **Generar migración.** El default `red` asegura que las evidencias existentes se asignen correctamente. **Validación:** - [ ] `alembic upgrade head` añade la columna `team` y `notes` a la tabla `evidences` - [ ] Las evidencias existentes tienen `team = 'red'` por defecto - [ ] Se puede insertar una evidencia con `team = 'blue'` - [ ] La columna `notes` acepta texto largo --- ### T-102: Campos de validación dual en Test (red_lead + blue_lead) **Objetivo:** Extender el modelo Test para soportar validación independiente por Red Lead y Blue Lead, de manera que un test solo pase a `validated` cuando ambos managers lo aprueban. **Archivos a modificar:** - `backend/app/models/test.py` **Nuevos campos:** | Campo | Tipo | Restricciones | |----------------------|----------|----------------------------------------| | red_validated_by | UUID | FK → users.id, nullable | | red_validated_at | DateTime | nullable | | red_validation_status| String | nullable (pending/approved/rejected) | | red_validation_notes | Text | nullable | | blue_validated_by | UUID | FK → users.id, nullable | | blue_validated_at | DateTime | nullable | | blue_validation_status| String | nullable (pending/approved/rejected) | | blue_validation_notes| Text | nullable | | red_summary | Text | nullable (resumen del ataque por red) | | blue_summary | Text | nullable (resumen de detección por blue)| | detection_result | Enum(TestResult) | nullable (resultado de detección blue) | | attack_success | Boolean | nullable (si el ataque tuvo éxito) | **Relaciones nuevas:** ```python red_validator = relationship("User", foreign_keys=[red_validated_by]) blue_validator = relationship("User", foreign_keys=[blue_validated_by]) ``` **Generar migración.** **Validación:** - [ ] `alembic upgrade head` crea las nuevas columnas sin errores - [ ] Los tests existentes tienen los nuevos campos como `null` - [ ] Se puede actualizar `red_validation_status` y `blue_validation_status` independientemente - [ ] Las FKs a `users.id` funcionan correctamente --- ### T-103: Modelo TestTemplate — catálogo de tests predefinidos **Objetivo:** Crear un modelo para almacenar plantillas de tests predefinidos (basados en Atomic Red Team, MITRE procedures, etc.) que los usuarios pueden instanciar como tests reales. **Archivo a crear:** `backend/app/models/test_template.py` **Campos:** | Campo | Tipo | Restricciones | |--------------------|----------|--------------------------------------------| | id | UUID | PK, default uuid4 | | mitre_technique_id | String | not null (ej: "T1059.001") | | name | String | not null | | description | Text | nullable | | source | String | not null (ej: "atomic_red_team", "mitre", "custom") | | source_url | String | nullable (URL al test original) | | attack_procedure | Text | nullable (procedimiento de ataque sugerido)| | expected_detection | Text | nullable (qué debería detectar blue team) | | platform | String | nullable (windows, linux, macos) | | tool_suggested | String | nullable (herramienta sugerida) | | severity | String | nullable (low, medium, high, critical) | | atomic_test_id | String | nullable (ID del test en Atomic Red Team) | | is_active | Boolean | default True | | created_at | DateTime | default utcnow | **Actualizar** `models/__init__.py` para importar TestTemplate. **Generar migración.** **Validación:** - [ ] `alembic upgrade head` crea la tabla `test_templates` - [ ] Se puede insertar un template con todos los campos - [ ] El campo `source` acepta los valores esperados - [ ] La tabla soporta múltiples templates para la misma técnica MITRE --- ### T-104: Schemas Pydantic para los nuevos modelos **Objetivo:** Crear schemas de request/response para los modelos modificados y nuevos. **Archivos a crear/modificar:** - `backend/app/schemas/test.py` — actualizar con nuevos campos - `backend/app/schemas/evidence.py` — añadir `team` y `notes` - `backend/app/schemas/test_template.py` — nuevo **Schemas de Test actualizados:** - `TestOut`: añadir campos de validación dual (`red_validated_by`, `blue_validated_by`, `red_validation_status`, `blue_validation_status`, `red_summary`, `blue_summary`, etc.) - `TestRedUpdate`: name, description, procedure_text, tool_used, attack_success, red_summary (campos que rellena Red Team) - `TestBlueUpdate`: detection_result, blue_summary (campos que rellena Blue Team) - `TestRedValidate`: red_validation_status (approved/rejected), red_validation_notes - `TestBlueValidate`: blue_validation_status (approved/rejected), blue_validation_notes **Schemas de Evidence actualizados:** - `EvidenceOut`: añadir `team` y `notes` - `EvidenceUpload`: añadir `team` (requerido) y `notes` (opcional) **Schemas de TestTemplate:** - `TestTemplateOut`: todos los campos - `TestTemplateCreate`: para crear templates personalizados - `TestTemplateSummary`: id, mitre_technique_id, name, source, platform, severity (para listados) - `TestTemplateInstantiate`: template_id, technique_id (para crear un test real desde un template) **Validación:** - [ ] Todos los schemas se importan sin errores - [ ] `TestOut` incluye los campos de validación dual - [ ] `TestTemplateCreate` valida correctamente los campos requeridos - [ ] `EvidenceOut` incluye `team` y `notes` --- ## FASE 11 — Lógica de Negocio del Flujo Red/Blue ### T-105: Servicio de transiciones de estado del Test **Objetivo:** Crear un servicio que controle las transiciones de estado válidas del test y garantice que solo se puedan hacer los cambios permitidos. **Archivo a crear:** `backend/app/services/test_workflow_service.py` **Transiciones válidas:** ```python VALID_TRANSITIONS = { TestState.draft: [TestState.red_executing], TestState.red_executing: [TestState.blue_evaluating], TestState.blue_evaluating: [TestState.in_review], TestState.in_review: [TestState.validated, TestState.rejected], TestState.rejected: [TestState.draft], TestState.validated: [], # estado final (o puede reabrirse) } ``` **Funciones a implementar:** - `can_transition(test: Test, target_state: TestState) -> bool` - `transition_state(db, test, target_state, user) -> Test` — valida transición, cambia estado, log de auditoría - `submit_red_evidence(db, test, user) -> Test` — marca como `blue_evaluating` cuando Red Team termina - `submit_blue_evidence(db, test, user) -> Test` — marca como `in_review` cuando Blue Team termina - `validate_as_red_lead(db, test, user, status, notes) -> Test` — valida parte Red - `validate_as_blue_lead(db, test, user, status, notes) -> Test` — valida parte Blue - `check_dual_validation(db, test) -> Test` — si ambos aprobaron, pasa a validated; si alguno rechazó, pasa a rejected **Validación:** - [ ] Transición draft → red_executing funciona - [ ] Transición draft → validated falla (no permitida) - [ ] Transición red_executing → blue_evaluating funciona - [ ] `check_dual_validation` pasa a validated solo si ambos managers aprobaron - [ ] `check_dual_validation` pasa a rejected si algún manager rechazó - [ ] Cada transición genera un log de auditoría --- ### T-106: Actualizar servicio de recalculación de status **Objetivo:** Mejorar `status_service.py` para tener en cuenta los nuevos estados y la validación dual. **Archivo a modificar:** `backend/app/services/status_service.py` **Nueva lógica:** ```python def recalculate_technique_status(db, technique): tests = technique.tests if not tests: technique.status_global = TechniqueStatus.not_evaluated elif all(t.state == TestState.validated for t in tests): # Todos validados — revisar resultados de detección results = [t.detection_result for t in tests if t.detection_result] if all(r == "detected" for r in results): technique.status_global = TechniqueStatus.validated elif any(r == "partially_detected" for r in results): technique.status_global = TechniqueStatus.partial else: technique.status_global = TechniqueStatus.not_covered elif any(t.state == TestState.validated for t in tests): technique.status_global = TechniqueStatus.partial else: technique.status_global = TechniqueStatus.in_progress db.commit() ``` **Validación:** - [ ] Sin tests → `not_evaluated` - [ ] Todos validated con detection=detected → `validated` - [ ] Algunos validated, otros en progreso → `partial` - [ ] Todos en estados intermedios → `in_progress` - [ ] Todos validated con detection=not_detected → `not_covered` --- ### T-107: Servicio de importación de Atomic Red Team **Objetivo:** Crear un servicio que importe tests predefinidos desde el repositorio de Atomic Red Team de Red Canary y los almacene como TestTemplates. **Archivo a crear:** `backend/app/services/atomic_import_service.py` **Lógica:** 1. Descargar/parsear el índice de Atomic Red Team desde GitHub (`https://github.com/redcanaryco/atomic-red-team`) 2. El repositorio contiene ficheros YAML organizados por técnica MITRE (`atomics/T1059.001/T1059.001.yaml`) 3. Para cada test atómico: - Extraer `name`, `description`, `supported_platforms`, `executor` (tipo y command) - Mapear a la técnica MITRE correspondiente - Crear un `TestTemplate` con `source = "atomic_red_team"` 4. No duplicar templates que ya existen (comparar por `atomic_test_id`) 5. Log de auditoría con resumen **Nota:** En el MVP, se puede hacer una importación simplificada usando la API de GitHub para obtener los YAML directamente, o descargar un JSON resumen pre-generado. **Validación:** - [ ] Ejecutar la importación crea TestTemplates en la BD - [ ] Cada template tiene `source = "atomic_red_team"` y datos válidos - [ ] Ejecutar dos veces no duplica templates - [ ] Los templates se mapean correctamente a técnicas MITRE existentes - [ ] Se importan al menos 50+ templates --- ## FASE 12 — Endpoints API Red/Blue ### T-108: Endpoints actualizados de Tests con flujo Red/Blue **Objetivo:** Modificar y añadir endpoints al router de tests para soportar el nuevo flujo de trabajo. **Archivo a modificar:** `backend/app/routers/tests.py` **Endpoints nuevos/modificados:** | Método | Ruta | Auth | Descripción | |--------|-----------------------------------|----------------------|------------------------------------------------| | GET | /tests | autenticado | Listar tests con filtros (state, technique_id) | | POST | /tests | red_tech, admin | Crear test (nuevo o desde template) | | POST | /tests/from-template | red_tech, admin | Crear test instanciando un template | | GET | /tests/{id} | autenticado | Detalle con evidencias separadas red/blue | | PATCH | /tests/{id}/red | red_tech, admin | Red Team actualiza su parte (procedure, tool, etc.) | | PATCH | /tests/{id}/blue | blue_tech, admin | Blue Team actualiza su parte (detection, summary) | | POST | /tests/{id}/submit-red | red_tech, admin | Red Team finaliza → pasa a blue_evaluating | | POST | /tests/{id}/submit-blue | blue_tech, admin | Blue Team finaliza → pasa a in_review | | POST | /tests/{id}/validate-red | red_lead, admin | Red Lead valida/rechaza parte red | | POST | /tests/{id}/validate-blue | blue_lead, admin | Blue Lead valida/rechaza parte blue | | POST | /tests/{id}/reopen | red_lead, blue_lead, admin | Reabrir test rechazado → draft | | GET | /tests/{id}/timeline | autenticado | Timeline de cambios de estado del test | **Detalle del endpoint GET /tests/{id}:** La respuesta debe incluir: ```json { "id": "...", "name": "...", "state": "blue_evaluating", "red_evidences": [...], // evidencias con team=red "blue_evidences": [...], // evidencias con team=blue "red_summary": "...", "blue_summary": "...", "attack_success": true, "detection_result": "detected", "red_validation_status": "approved", "blue_validation_status": "pending", "timeline": [...] // historial de cambios } ``` **Validación:** - [ ] `POST /tests` crea un test en estado `draft` - [ ] `POST /tests/from-template` crea un test con datos pre-rellenados del template - [ ] `PATCH /tests/{id}/red` solo funciona si el test está en `red_executing` - [ ] `PATCH /tests/{id}/blue` solo funciona si el test está en `blue_evaluating` - [ ] `POST /tests/{id}/submit-red` cambia estado a `blue_evaluating` - [ ] `POST /tests/{id}/submit-blue` cambia estado a `in_review` - [ ] `POST /tests/{id}/validate-red` solo accesible por red_lead - [ ] `POST /tests/{id}/validate-blue` solo accesible por blue_lead - [ ] Cuando ambos validan como approved → test pasa a `validated` - [ ] Cuando alguno rechaza → test pasa a `rejected` - [ ] `POST /tests/{id}/reopen` solo funciona en tests `rejected` - [ ] `GET /tests/{id}/timeline` retorna el historial ordenado cronológicamente - [ ] Cada operación genera audit log --- ### T-109: Endpoints de Evidence con separación Red/Blue **Objetivo:** Modificar el router de evidencias para soportar la separación por equipo. **Archivo a modificar:** `backend/app/routers/evidence.py` **Endpoints modificados:** | Método | Ruta | Auth | Descripción | |--------|-----------------------------------|-----------------|----------------------------------------------| | POST | /tests/{test_id}/evidence | autenticado | Subir evidencia indicando team (red/blue) | | GET | /tests/{test_id}/evidence | autenticado | Listar evidencias del test, filtrable por team | | GET | /evidence/{id} | autenticado | Obtener URL pre-firmada | | DELETE | /evidence/{id} | creador o admin | Eliminar evidencia (solo en estados editables)| **Lógica de control:** - Red Team solo puede subir evidencias `team=red` cuando el test está en `red_executing` - Blue Team solo puede subir evidencias `team=blue` cuando el test está en `blue_evaluating` - Admin puede subir en cualquier momento **Validación:** - [ ] Un `red_tech` puede subir evidencia con `team=red` en estado `red_executing` - [ ] Un `red_tech` NO puede subir evidencia con `team=blue` - [ ] Un `blue_tech` puede subir evidencia con `team=blue` en estado `blue_evaluating` - [ ] Un `blue_tech` NO puede subir evidencia con `team=red` - [ ] `GET /tests/{id}/evidence?team=red` filtra correctamente - [ ] `DELETE /evidence/{id}` solo permite borrar en estados editables - [ ] Admin puede subir cualquier tipo de evidencia en cualquier momento --- ### T-110: Endpoints CRUD de TestTemplates **Objetivo:** Crear endpoints para gestionar el catálogo de templates de tests. **Archivo a crear:** `backend/app/routers/test_templates.py` **Endpoints:** | Método | Ruta | Auth | Descripción | |--------|-----------------------------------|-----------------|----------------------------------------------| | GET | /test-templates | autenticado | Listar templates con filtros | | GET | /test-templates/{id} | autenticado | Detalle de un template | | POST | /test-templates | admin | Crear template personalizado | | PATCH | /test-templates/{id} | admin | Actualizar template | | DELETE | /test-templates/{id} | admin | Desactivar template (soft delete) | | GET | /test-templates/by-technique/{mitre_id} | autenticado | Templates para una técnica MITRE específica | **Filtros del GET /test-templates:** - `source`: atomic_red_team, mitre, custom - `platform`: windows, linux, macos - `severity`: low, medium, high, critical - `mitre_technique_id`: filtrar por técnica - `search`: búsqueda por nombre/descripción **Validación:** - [ ] `GET /test-templates` retorna lista paginada - [ ] `GET /test-templates?source=atomic_red_team` filtra por fuente - [ ] `GET /test-templates?platform=windows` filtra por plataforma - [ ] `GET /test-templates/by-technique/T1059.001` retorna templates para esa técnica - [ ] `POST /test-templates` solo accesible por admin - [ ] `DELETE /test-templates/{id}` hace soft delete (is_active=False) - [ ] El filtro `search` busca en name y description --- ### T-111: Endpoint de importación de Atomic Red Team **Objetivo:** Exponer la importación de Atomic Red Team como endpoint del sistema. **Archivo a modificar:** `backend/app/routers/system.py` **Endpoint:** ``` POST /api/v1/system/import-atomic-tests Auth: admin only Response: {"message": "Import completed", "imported": X, "skipped": Y, "errors": Z} ``` **Validación:** - [ ] `POST /system/import-atomic-tests` ejecuta la importación y retorna estadísticas - [ ] Solo admin puede ejecutar - [ ] Audit log registra la importación - [ ] Ejecutar dos veces no duplica — incrementa `skipped` --- ## FASE 13 — Frontend: Tipos y API Clients ### T-112: Actualizar tipos TypeScript **Objetivo:** Actualizar los tipos del frontend para reflejar los cambios del backend. **Archivo a modificar:** `frontend/src/types/models.ts` **Tipos a añadir/modificar:** ```typescript // Actualizar TestState export type TestState = | "draft" | "red_executing" | "blue_evaluating" | "in_review" | "validated" | "rejected"; // Nuevo tipo TeamSide export type TeamSide = "red" | "blue"; // Actualizar Evidence export interface Evidence { id: string; test_id: string; file_name: string; file_path: string; sha256_hash: string; uploaded_by: string | null; uploaded_at: string; team: TeamSide; notes: string | null; } // Actualizar Test con campos duales export interface Test { // ... campos existentes ... red_summary: string | null; blue_summary: string | null; attack_success: boolean | null; detection_result: TestResult | null; red_validation_status: ValidationStatus | null; blue_validation_status: ValidationStatus | null; red_validation_notes: string | null; blue_validation_notes: string | null; red_validated_by: string | null; blue_validated_by: string | null; red_evidences: Evidence[]; blue_evidences: Evidence[]; } export type ValidationStatus = "pending" | "approved" | "rejected"; // Nuevo tipo TestTemplate export interface TestTemplate { id: string; mitre_technique_id: string; name: string; description: string | null; source: string; source_url: string | null; attack_procedure: string | null; expected_detection: string | null; platform: string | null; tool_suggested: string | null; severity: string | null; atomic_test_id: string | null; is_active: boolean; created_at: string; } // Timeline export interface TestTimelineEntry { id: string; action: string; user: string; timestamp: string; details: Record; } ``` **Validación:** - [ ] TypeScript compila sin errores - [ ] Todos los tipos nuevos están exportados - [ ] Los tipos coinciden con los schemas del backend --- ### T-113: Nuevos API clients **Objetivo:** Crear/actualizar los clientes API del frontend para los nuevos endpoints. **Archivos a crear/modificar:** - `frontend/src/api/tests.ts` — actualizar con nuevos endpoints - `frontend/src/api/evidence.ts` — actualizar con parámetro `team` - `frontend/src/api/test-templates.ts` — nuevo **Funciones nuevas en tests.ts:** ```typescript export const createTestFromTemplate = (templateId: string, techniqueId: string) => ... export const updateTestRed = (testId: string, data: RedUpdateData) => ... export const updateTestBlue = (testId: string, data: BlueUpdateData) => ... export const submitRedEvidence = (testId: string) => ... export const submitBlueEvidence = (testId: string) => ... export const validateAsRedLead = (testId: string, data: RedValidation) => ... export const validateAsBlueLead = (testId: string, data: BlueValidation) => ... export const reopenTest = (testId: string) => ... export const getTestTimeline = (testId: string) => ... ``` **Funciones nuevas en evidence.ts:** ```typescript export const uploadEvidence = (testId: string, file: File, team: TeamSide, notes?: string) => ... export const getTestEvidences = (testId: string, team?: TeamSide) => ... export const deleteEvidence = (evidenceId: string) => ... ``` **Funciones en test-templates.ts:** ```typescript export const getTemplates = (filters?: TemplateFilters) => ... export const getTemplateById = (id: string) => ... export const getTemplatesByTechnique = (mitreId: string) => ... export const createTemplate = (data: CreateTemplate) => ... export const importAtomicTests = () => ... ``` **Validación:** - [ ] Todos los imports funcionan sin errores TypeScript - [ ] Cada función envía la petición al endpoint correcto - [ ] `uploadEvidence` incluye el campo `team` en FormData - [ ] `getTestEvidences` envía el query param `team` correctamente --- ## FASE 14 — Frontend: Página de Test Rediseñada con Pestañas Red/Blue ### T-114: Componente TestDetailHeader **Objetivo:** Crear el header del detalle del test con información del estado, progreso y acciones contextuales. **Archivo a crear:** `frontend/src/components/test-detail/TestDetailHeader.tsx` **Contenido:** - Nombre del test y badge de estado con color - Barra de progreso visual (5 pasos: draft → red → blue → review → validated) - Nombre de la técnica asociada (link) - Botones de acción contextuales según rol y estado: - Red Tech en `red_executing`: botón "Submit to Blue Team" - Blue Tech en `blue_evaluating`: botón "Submit for Review" - Red Lead en `in_review`: botón "Approve/Reject Red" - Blue Lead en `in_review`: botón "Approve/Reject Blue" - Indicadores de validación dual (checkmarks para red_lead y blue_lead) **Validación:** - [ ] El header muestra toda la información correcta - [ ] La barra de progreso refleja el estado actual - [ ] Los botones aparecen solo cuando el rol y estado lo permiten - [ ] Los indicadores de validación dual se actualizan correctamente --- ### T-115: Componente de pestañas Red Team / Blue Team **Objetivo:** Crear el sistema de pestañas que separa las evidencias y el contenido entre Red Team y Blue Team. **Archivo a crear:** `frontend/src/components/test-detail/TeamTabs.tsx` **Estructura de pestañas:** ``` ┌──────────────────────────────────────────────────────────────┐ │ [🔴 Red Team] [🔵 Blue Team] [📋 Summary] [📜 Timeline] │ ├──────────────────────────────────────────────────────────────┤ │ │ │ Contenido de la pestaña seleccionada │ │ │ └──────────────────────────────────────────────────────────────┘ ``` **Pestaña Red Team:** - Procedimiento de ataque (editable en `red_executing`) - Herramienta utilizada - Indicador de éxito del ataque (switch: sí/no) - Resumen del Red Team (textarea) - Lista de evidencias Red con upload (solo en `red_executing` para red_tech) - Estado de validación del Red Lead (si aplica) **Pestaña Blue Team:** - Resultado de detección (detected/not_detected/partially_detected) - Resumen del Blue Team (textarea) - Lista de evidencias Blue con upload (solo en `blue_evaluating` para blue_tech) - Estado de validación del Blue Lead (si aplica) **Pestaña Summary:** - Vista resumen con ambos lados lado a lado - Comparativa visual: ataque vs detección - Resultado final **Pestaña Timeline:** - Historial cronológico de todos los cambios del test - Cada entrada con usuario, acción, fecha y detalles **Validación:** - [ ] Las pestañas se renderizan correctamente - [ ] Cambiar de pestaña muestra el contenido correcto - [ ] Los campos son editables solo en el estado y rol apropiados - [ ] Upload de evidencias funciona dentro de cada pestaña - [ ] La pestaña Summary muestra comparativa correcta --- ### T-116: Página TestDetailPage rediseñada **Objetivo:** Integrar los nuevos componentes en la página de detalle del test, reemplazando el diseño actual. **Archivo a modificar:** `frontend/src/pages/TestDetailPage.tsx` **Estructura:** ``` ┌─────────────────────────────────────────────────────────┐ │ TestDetailHeader (estado, progreso, acciones) │ ├─────────────────────────────────────────────────────────┤ │ │ │ TeamTabs │ │ ┌─────────────────────────────────────────────────────┐│ │ │ Pestaña seleccionada (Red/Blue/Summary/Timeline) ││ │ └─────────────────────────────────────────────────────┘│ │ │ ├─────────────────────────────────────────────────────────┤ │ Sidebar: Metadata del test │ │ - Técnica asociada │ │ - Plataforma │ │ - Creador │ │ - Fechas │ │ - Template origen (si aplica) │ └─────────────────────────────────────────────────────────┘ ``` **Interacciones:** - Toda acción usa mutations de react-query con invalidación - Modales de confirmación para validar/rechazar - Toast notifications para feedback - Loading states en todas las operaciones **Validación:** - [ ] La página carga y muestra todos los datos del test - [ ] Las pestañas Red/Blue/Summary/Timeline funcionan - [ ] Las acciones de validación dual funcionan correctamente - [ ] La transición de estado se refleja en tiempo real tras cada acción - [ ] Los permisos de edición se respetan según rol y estado - [ ] La subida de evidencias funciona dentro de las pestañas --- ### T-117: Modal de Validación Dual **Objetivo:** Crear un modal de validación que permita a los managers aprobar o rechazar su parte del test, con notas obligatorias en caso de rechazo. **Archivo a crear:** `frontend/src/components/test-detail/ValidationModal.tsx` **Contenido:** - Título: "Validate as Red Lead" / "Validate as Blue Lead" - Resumen de evidencias del equipo correspondiente - Opciones: Approve / Reject - Textarea para notas (obligatorio en rechazo) - Indicador visual del estado de la otra validación - Botón de confirmar con loading state **Validación:** - [ ] El modal aparece al hacer click en Validate - [ ] Se puede seleccionar Approve o Reject - [ ] Reject requiere notas obligatorias — botón deshabilitado sin notas - [ ] Approve envía la petición y cierra el modal - [ ] Se muestra el estado de la validación del otro manager - [ ] Loading state funciona durante la petición --- ## FASE 15 — Frontend: Catálogo de Tests y Creación desde Templates ### T-118: Página de catálogo de TestTemplates **Objetivo:** Crear una página donde los usuarios puedan explorar el catálogo de tests disponibles, filtrar por técnica, plataforma y fuente, y ver el detalle de cada template. **Archivo a crear:** `frontend/src/pages/TestCatalogPage.tsx` **Componentes necesarios:** - Barra de búsqueda y filtros (source, platform, severity, technique) - Grid/lista de templates con cards - Cada card muestra: nombre, técnica MITRE, plataforma, severidad, fuente (badge), botón "Use Template" - Paginación **Ruta:** `/test-catalog` — añadir al router y al sidebar. **Validación:** - [ ] La página carga y muestra templates del backend - [ ] Los filtros funcionan (source, platform, severity, search) - [ ] Cada card muestra la información correcta - [ ] El botón "Use Template" navega o abre modal de instanciación - [ ] Responsive en móvil y desktop --- ### T-119: Modal/Página de instanciación de Template **Objetivo:** Permitir crear un test real a partir de un template, pre-rellenando los campos y permitiendo modificaciones. **Archivo a crear:** `frontend/src/components/TestFromTemplateForm.tsx` **Flujo:** 1. El usuario selecciona un template (desde el catálogo o desde la vista de técnica) 2. Se abre un formulario pre-rellenado con los datos del template 3. El usuario puede modificar los campos 4. Al guardar, se crea un test real con `state=draft` **Campos del formulario:** - Nombre (pre-rellenado) - Descripción (pre-rellenado) - Técnica asociada (pre-rellenado si se viene de una técnica) - Plataforma (pre-rellenado) - Procedimiento de ataque sugerido (pre-rellenado, editable) - Herramienta sugerida (pre-rellenado, editable) - Detección esperada (pre-rellenado, readonly — referencia para blue team) **Validación:** - [ ] El formulario se pre-rellena con datos del template - [ ] Se puede modificar cualquier campo editable - [ ] Submit crea el test y redirige al detalle - [ ] El test creado tiene referencia al template origen - [ ] Campos requeridos se validan antes de submit --- ### T-120: Integrar catálogo en vista de Técnica **Objetivo:** Desde la página de detalle de una técnica, permitir ver los templates disponibles y crear tests directamente. **Archivo a modificar:** `frontend/src/pages/TechniqueDetailPage.tsx` **Cambios:** - Añadir sección "Available Test Templates" debajo de los tests existentes - Mostrar cards resumidas de templates disponibles para esa técnica - Botón "Run This Test" en cada template que abre el formulario de instanciación - Si no hay templates, mostrar mensaje y link al catálogo general **Validación:** - [ ] La sección de templates aparece en la página de técnica - [ ] Se muestran solo los templates para esa técnica MITRE - [ ] "Run This Test" pre-rellena correctamente el formulario - [ ] Si no hay templates se muestra mensaje apropiado - [ ] La creación del test actualiza la lista de tests de la técnica --- ## FASE 16 — Frontend: Vistas de Gestión y Dashboard Mejorado ### T-121: Vista de Tests mejorada con filtros por estado y equipo **Objetivo:** Mejorar la página de listado de tests con filtros avanzados y vistas específicas por equipo. **Archivo a modificar:** `frontend/src/pages/TestsPage.tsx` **Mejoras:** - Filtros: por estado (todos los nuevos estados), por equipo asignado, por técnica, por plataforma - Vista de "Mis tareas pendientes" según rol: - Red Tech: tests en `draft` o `red_executing` creados por mí - Blue Tech: tests en `blue_evaluating` - Red Lead: tests en `in_review` pendientes de validación red - Blue Lead: tests en `in_review` pendientes de validación blue - Estadísticas rápidas: contadores por estado (cards superiores) - Tabla con columnas: nombre, técnica, estado, equipo actual, última actualización, acciones **Validación:** - [ ] Los filtros por estado funcionan con los nuevos estados - [ ] "Mis tareas pendientes" filtra correctamente según el rol del usuario - [ ] Los contadores por estado son correctos - [ ] La tabla muestra toda la información necesaria - [ ] Click en un test navega al detalle --- ### T-122: Dashboard mejorado con métricas Red/Blue **Objetivo:** Añadir al dashboard métricas específicas del flujo de validación Red/Blue. **Archivos a modificar:** - `backend/app/routers/metrics.py` — añadir nuevos endpoints - `backend/app/schemas/metrics.py` — añadir nuevos schemas - `frontend/src/pages/DashboardPage.tsx` — añadir nuevas secciones **Nuevos endpoints de métricas:** ``` GET /metrics/test-pipeline → contadores por estado del pipeline GET /metrics/team-activity → actividad por equipo (tests completados, pendientes) GET /metrics/validation-rate → tasa de aprobación/rechazo por manager ``` **Nuevas secciones del dashboard:** 1. **Pipeline de Tests**: gráfico de funnel mostrando cuántos tests hay en cada estado 2. **Actividad por equipo**: Red Team vs Blue Team — tests completados, tiempo medio 3. **Tasa de validación**: porcentaje de aprobación por Red Lead y Blue Lead 4. **Tests recientes**: tabla con los últimos 10 tests actualizados **Validación:** - [ ] Los nuevos endpoints retornan datos correctos - [ ] El dashboard muestra las nuevas secciones - [ ] El pipeline de tests refleja los estados reales - [ ] Las métricas de equipo se calculan correctamente - [ ] La sección de tests recientes se actualiza --- ### T-123: Panel de administración de Templates **Objetivo:** Añadir al panel de sistema la gestión de templates: importar Atomic Red Team, crear templates personalizados, ver estadísticas del catálogo. **Archivo a modificar:** `frontend/src/pages/SystemPage.tsx` **Nuevas secciones:** 1. **Importar Atomic Red Team**: botón para ejecutar importación, con progreso y resultado 2. **Estadísticas del catálogo**: total templates, por fuente, por plataforma 3. **Crear template personalizado**: formulario inline o modal 4. **Gestionar templates**: tabla con opción de activar/desactivar **Validación:** - [ ] Botón de importación ejecuta y muestra resultados - [ ] Las estadísticas del catálogo se muestran correctamente - [ ] Se puede crear un template personalizado - [ ] Se puede desactivar un template - [ ] Solo admin puede acceder a estas funciones --- ## FASE 17 — Backend Tests Automatizados ### T-124: Tests del flujo de trabajo Red/Blue **Objetivo:** Crear tests automatizados que verifiquen todo el ciclo de vida de un test de seguridad. **Archivo a crear:** `backend/tests/test_workflow.py` **Tests a implementar:** ```python class TestWorkflow: def test_full_happy_path(): """draft → red_executing → blue_evaluating → in_review → validated""" def test_rejection_and_reopen(): """in_review → rejected → draft → red_executing → ...""" def test_invalid_transitions(): """Verificar que transiciones no válidas fallan""" def test_red_tech_cannot_access_blue_phase(): """Red tech no puede editar en blue_evaluating""" def test_blue_tech_cannot_access_red_phase(): """Blue tech no puede editar en red_executing""" def test_dual_validation_both_approve(): """Ambos managers aprueban → validated""" def test_dual_validation_one_rejects(): """Un manager rechaza → rejected""" def test_evidence_team_separation(): """Evidencias red y blue se separan correctamente""" ``` **Validación:** - [ ] `pytest tests/test_workflow.py` ejecuta todos los tests - [ ] Todos los tests pasan (verde) - [ ] Cobertura del flujo completo --- ### T-125: Tests de TestTemplates **Objetivo:** Tests automatizados para el CRUD de templates y la instanciación. **Archivo a crear:** `backend/tests/test_templates.py` **Tests:** ```python class TestTemplates: def test_create_template(): """Admin puede crear un template""" def test_list_templates_with_filters(): """Filtros de source, platform, severity funcionan""" def test_get_templates_by_technique(): """Filtrar templates por técnica MITRE""" def test_instantiate_template(): """Crear test desde template pre-rellena campos""" def test_soft_delete_template(): """Desactivar template no lo borra físicamente""" def test_non_admin_cannot_create_template(): """Solo admin puede crear templates""" ``` **Validación:** - [ ] `pytest tests/test_templates.py` pasa todos los tests - [ ] Cobertura de CRUD y filtros - [ ] Cobertura de permisos --- ### T-126: Tests de métricas actualizadas **Objetivo:** Tests automatizados para los nuevos endpoints de métricas. **Archivo a crear:** `backend/tests/test_metrics_v2.py` **Tests:** ```python class TestMetricsV2: def test_pipeline_metrics(): """Contadores por estado del pipeline correctos""" def test_team_activity_metrics(): """Actividad por equipo calculada correctamente""" def test_technique_status_recalculation_with_new_states(): """Recalculación funciona con los nuevos estados""" def test_coverage_with_dual_validation(): """Cobertura correcta tras validación dual""" ``` **Validación:** - [ ] `pytest tests/test_metrics_v2.py` pasa todos los tests - [ ] Las métricas coinciden con los datos de prueba --- ## FASE 18 — Notificaciones y Sidebar de Actividad ### T-127: Modelo de notificaciones **Objetivo:** Crear un sistema básico de notificaciones in-app para alertar a los usuarios cuando necesitan actuar. **Archivo a crear:** `backend/app/models/notification.py` **Campos:** | Campo | Tipo | Restricciones | |-----------|----------|------------------------------------| | id | UUID | PK, default uuid4 | | user_id | UUID | FK → users.id, not null | | type | String | not null (test_assigned, validation_needed, test_rejected, etc.) | | title | String | not null | | message | Text | nullable | | entity_type | String | nullable (test, technique) | | entity_id | UUID | nullable | | read | Boolean | default False | | created_at| DateTime | default utcnow | **Generar migración.** **Servicio** `backend/app/services/notification_service.py`: ```python def create_notification(db, user_id, type, title, message, entity_type, entity_id) def mark_as_read(db, notification_id, user_id) def mark_all_as_read(db, user_id) def get_unread_count(db, user_id) -> int ``` **Disparar notificaciones automáticamente:** - Cuando un test pasa a `blue_evaluating` → notificar a todos los `blue_tech` - Cuando un test pasa a `in_review` → notificar a `red_lead` y `blue_lead` - Cuando un test es rechazado → notificar al creador - Cuando un test es validado → notificar al creador **Validación:** - [ ] Se crea una notificación cuando un test cambia a `blue_evaluating` - [ ] Se crea una notificación para managers cuando un test llega a `in_review` - [ ] Se crea una notificación al creador cuando un test es rechazado - [ ] Se crea una notificación al creador cuando un test es validado - [ ] `get_unread_count` retorna el número correcto --- ### T-128: Endpoints y frontend de notificaciones **Objetivo:** Endpoints API y UI de notificaciones. **Archivos a crear:** - `backend/app/routers/notifications.py` - `frontend/src/api/notifications.ts` - `frontend/src/components/NotificationBell.tsx` - `frontend/src/components/NotificationDropdown.tsx` **Endpoints:** | Método | Ruta | Auth | Descripción | |--------|-----------------------------|-------------|-------------------------------| | GET | /notifications | autenticado | Listar notificaciones del user| | GET | /notifications/unread-count | autenticado | Contador de no leídas | | PATCH | /notifications/{id}/read | autenticado | Marcar como leída | | POST | /notifications/read-all | autenticado | Marcar todas como leídas | **Frontend:** - `NotificationBell`: icono de campana en el header con badge de conteo - `NotificationDropdown`: dropdown con lista de notificaciones - Click en notificación navega a la entidad correspondiente y marca como leída - Polling cada 30 segundos para actualizar conteo (o usar react-query con refetchInterval) **Validación:** - [ ] La campana muestra el conteo correcto de no leídas - [ ] El dropdown lista las notificaciones ordenadas por fecha - [ ] Click en una notificación navega correctamente y marca como leída - [ ] "Mark all as read" limpia el conteo - [ ] Las notificaciones se generan automáticamente con los cambios de estado --- ## FASE 19 — Mejoras de Remediación y Reportes (inspirado en Validato) ### T-129: Campo de remediación en tests y templates **Objetivo:** Añadir campos de remediación y recomendaciones, inspirados en el enfoque de Validato de "step-by-step remediation". **Archivos a modificar:** - `backend/app/models/test.py` — nuevos campos - `backend/app/models/test_template.py` — nuevo campo - Schemas correspondientes **Nuevos campos en Test:** | Campo | Tipo | Restricciones | |----------------------|--------|---------------| | remediation_steps | Text | nullable | | remediation_status | String | nullable (pending, in_progress, completed, not_applicable) | | remediation_assignee | UUID | FK → users.id, nullable | **Nuevo campo en TestTemplate:** | Campo | Tipo | Restricciones | |---------------------------|--------|---------------| | suggested_remediation | Text | nullable | **Generar migración.** **Validación:** - [ ] Los nuevos campos se crean en la BD - [ ] Se pueden asignar pasos de remediación a un test - [ ] Se puede asignar un responsable de remediación - [ ] El template puede sugerir remediación al instanciar --- ### T-130: Endpoint y UI de reportes **Objetivo:** Crear un sistema básico de reportes que permita exportar el estado de cobertura en diferentes formatos. **Archivos a crear:** - `backend/app/routers/reports.py` - `frontend/src/pages/ReportsPage.tsx` **Endpoints:** | Método | Ruta | Auth | Descripción | |--------|--------------------------------|-------------|-----------------------------------| | GET | /reports/coverage-summary | autenticado | Reporte JSON completo | | GET | /reports/coverage-csv | autenticado | Export CSV de cobertura | | GET | /reports/test-results | autenticado | Reporte de resultados de tests | | GET | /reports/remediation-status | autenticado | Reporte de estado de remediación | **Página de reportes:** - Selector de tipo de reporte - Filtros (rango de fechas, tácticas, plataformas) - Preview del reporte - Botones de descarga (CSV, JSON) - Resumen visual con métricas clave **Ruta:** `/reports` — añadir al router y sidebar. **Validación:** - [ ] Cada endpoint retorna datos correctos - [ ] El CSV se descarga y abre correctamente en Excel - [ ] Los filtros funcionan en el frontend - [ ] La preview del reporte se muestra correctamente - [ ] Solo usuarios autenticados pueden acceder --- ## FASE 20 — Pulido Final y Documentación ### T-131: Actualizar navegación y routing **Objetivo:** Integrar todas las nuevas páginas en la navegación de la aplicación. **Archivos a modificar:** - `frontend/src/App.tsx` — nuevas rutas - `frontend/src/components/Sidebar.tsx` — nuevos items **Nuevas rutas:** ``` /test-catalog → TestCatalogPage /tests/:testId → TestDetailPage (rediseñada) /reports → ReportsPage ``` **Items del sidebar:** - Dashboard - ATT&CK Matrix (Techniques) - Tests (con submenu) - All Tests - My Pending Tasks - Test Catalog - Reports - System (admin) - MITRE Sync - Intel Scan - Templates Management - Users - Audit Log **Validación:** - [ ] Todas las rutas nuevas funcionan - [ ] El sidebar muestra los items correctos según el rol - [ ] La navegación entre páginas es fluida - [ ] No hay rutas rotas o 404 --- ### T-132: Error handling y edge cases **Objetivo:** Asegurar que todos los nuevos flujos manejan errores correctamente. **Verificaciones:** **Backend:** - Todos los endpoints nuevos tienen manejo de 404, 400, 403 - Las transiciones de estado inválidas retornan errores descriptivos - Los permisos de equipo se validan en cada endpoint **Frontend:** - Loading states en todas las operaciones nuevas - Error messages descriptivos en validaciones y transiciones - Confirmación antes de acciones destructivas (rechazar, reabrir) - Feedback visual tras cada acción exitosa (toast) **Validación:** - [ ] Intentar transición inválida muestra error descriptivo - [ ] Permisos incorrectos muestran 403 con mensaje claro - [ ] Loading states aparecen en todas las operaciones - [ ] Toast de éxito tras cada acción exitosa - [ ] Modal de confirmación antes de rechazar un test --- ### T-133: Backend tests finales de integración **Objetivo:** Suite final de tests que verifica el sistema completo end-to-end. **Archivo a crear:** `backend/tests/test_integration.py` **Tests:** ```python class TestIntegration: def test_full_e2e_flow(): """ 1. Admin importa Atomic Red Team templates 2. Red Tech crea test desde template 3. Red Tech sube evidencias y submite 4. Blue Tech evalúa y sube evidencias 5. Blue Tech submite para review 6. Red Lead y Blue Lead validan 7. Verificar que la técnica cambia de estado """ def test_rejection_recovery_flow(): """Flujo completo con rechazo y recuperación""" def test_notification_flow(): """Verificar que las notificaciones se generan correctamente""" def test_metrics_accuracy(): """Verificar que las métricas son correctas tras operaciones""" def test_report_generation(): """Verificar generación de reportes""" ``` **Validación:** - [ ] `pytest tests/test_integration.py` pasa todos los tests - [ ] El flujo E2E completo funciona sin errores - [ ] Las métricas son consistentes tras todas las operaciones --- ### T-134: Actualizar documentación **Objetivo:** Actualizar README y documentación API para reflejar todos los cambios. **Archivos a modificar:** - `README.md` — actualizar con nuevas funcionalidades - `docs/API.md` — documentar nuevos endpoints **Secciones nuevas en README:** - Descripción del flujo Red Team / Blue Team - Descripción de los roles y permisos - Cómo importar tests de Atomic Red Team - Cómo usar el catálogo de templates - Explicación del ciclo de vida de un test - Diagrama del flujo de validación dual **Documentación API:** - Nuevos endpoints de tests (flujo Red/Blue) - Endpoints de templates - Endpoints de notificaciones - Endpoints de reportes - Nuevos endpoints de métricas **Validación:** - [ ] El README refleja todas las funcionalidades nuevas - [ ] La documentación API cubre todos los endpoints nuevos - [ ] Swagger UI en /docs muestra todos los endpoints correctamente - [ ] Siguiendo el README, un nuevo desarrollador puede entender el flujo completo --- ## Resumen de Fases | Fase | Tareas | Descripción | |------|------------------|-------------------------------------------------------| | 10 | T-100 a T-104 | Evolución del modelo de datos para Red/Blue Team | | 11 | T-105 a T-107 | Lógica de negocio del flujo Red/Blue | | 12 | T-108 a T-111 | Endpoints API Red/Blue | | 13 | T-112 a T-113 | Frontend: tipos y API clients | | 14 | T-114 a T-117 | Frontend: página de test con pestañas Red/Blue | | 15 | T-118 a T-120 | Frontend: catálogo de tests y templates | | 16 | T-121 a T-123 | Frontend: vistas de gestión y dashboard mejorado | | 17 | T-124 a T-126 | Backend tests automatizados | | 18 | T-127 a T-128 | Notificaciones in-app | | 19 | T-129 a T-130 | Remediación y reportes | | 20 | T-131 a T-134 | Pulido final y documentación | > **Total: 35 tareas = 35 commits mínimo** > Cada tarea es autocontenida y verificable antes de hacer commit. --- ## Inspiración de Validato Las siguientes ideas están inspiradas en la plataforma [Validato](https://validato.io/) y adaptadas al contexto de Aegis: 1. **Tests mapeados a MITRE ATT&CK**: Cada test está directamente vinculado a una técnica, igual que Validato mapea simulaciones a TTPs. 2. **Catálogo de tests predefinidos**: Similar a cómo Validato ofrece escenarios de validación pre-configurados, Aegis usa Atomic Red Team como fuente de tests base. 3. **Validación de Protection + Detection**: Validato evalúa si los controles protegen Y detectan. En Aegis, Red Team valida la ejecución del ataque y Blue Team valida la detección. 4. **Resultados mapeados a frameworks**: Los resultados se mapean de vuelta a MITRE ATT&CK para actualizar la cobertura. 5. **Remediación paso a paso**: Inspirado en cómo Validato proporciona remediation steps, cada test puede incluir pasos de remediación sugeridos. 6. **Validación continua**: El pipeline draft → red → blue → review → validated permite re-ejecutar tests continuamente para medir mejoras. 7. **Reportes de cobertura**: Exportación de reportes para demostrar compliance (similar a los reportes de Validato para DORA, NIS2, GLBA). 8. **Priorización por severidad**: Los templates incluyen severidad para priorizar qué tests ejecutar primero.