56 KiB
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. 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:
- Atomic Red Team (Red Canary): repositorio open-source con tests atómicos mapeados a MITRE ATT&CK
- MITRE ATT&CK procedures: procedimientos documentados en la propia base de datos de MITRE
- 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:
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 headaplica 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 -1revierte 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 enumTeamSidebackend/app/models/evidence.py— añadir campoteam
Nuevo enum:
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 headañade la columnateamynotesa la tablaevidences- Las evidencias existentes tienen
team = 'red'por defecto - Se puede insertar una evidencia con
team = 'blue' - La columna
notesacepta 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:
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 headcrea las nuevas columnas sin errores- Los tests existentes tienen los nuevos campos como
null - Se puede actualizar
red_validation_statusyblue_validation_statusindependientemente - Las FKs a
users.idfuncionan 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 headcrea la tablatest_templates- Se puede insertar un template con todos los campos
- El campo
sourceacepta 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 camposbackend/app/schemas/evidence.py— añadirteamynotesbackend/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_notesTestBlueValidate: blue_validation_status (approved/rejected), blue_validation_notes
Schemas de Evidence actualizados:
EvidenceOut: añadirteamynotesEvidenceUpload: añadirteam(requerido) ynotes(opcional)
Schemas de TestTemplate:
TestTemplateOut: todos los camposTestTemplateCreate: para crear templates personalizadosTestTemplateSummary: 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
TestOutincluye los campos de validación dualTestTemplateCreatevalida correctamente los campos requeridosEvidenceOutincluyeteamynotes
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:
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) -> booltransition_state(db, test, target_state, user) -> Test— valida transición, cambia estado, log de auditoríasubmit_red_evidence(db, test, user) -> Test— marca comoblue_evaluatingcuando Red Team terminasubmit_blue_evidence(db, test, user) -> Test— marca comoin_reviewcuando Blue Team terminavalidate_as_red_lead(db, test, user, status, notes) -> Test— valida parte Redvalidate_as_blue_lead(db, test, user, status, notes) -> Test— valida parte Bluecheck_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_validationpasa a validated solo si ambos managers aprobaroncheck_dual_validationpasa 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:
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:
- Descargar/parsear el índice de Atomic Red Team desde GitHub (
https://github.com/redcanaryco/atomic-red-team) - El repositorio contiene ficheros YAML organizados por técnica MITRE (
atomics/T1059.001/T1059.001.yaml) - Para cada test atómico:
- Extraer
name,description,supported_platforms,executor(tipo y command) - Mapear a la técnica MITRE correspondiente
- Crear un
TestTemplateconsource = "atomic_red_team"
- Extraer
- No duplicar templates que ya existen (comparar por
atomic_test_id) - 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:
{
"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 /testscrea un test en estadodraftPOST /tests/from-templatecrea un test con datos pre-rellenados del templatePATCH /tests/{id}/redsolo funciona si el test está enred_executingPATCH /tests/{id}/bluesolo funciona si el test está enblue_evaluatingPOST /tests/{id}/submit-redcambia estado ablue_evaluatingPOST /tests/{id}/submit-bluecambia estado ain_reviewPOST /tests/{id}/validate-redsolo accesible por red_leadPOST /tests/{id}/validate-bluesolo accesible por blue_lead- Cuando ambos validan como approved → test pasa a
validated - Cuando alguno rechaza → test pasa a
rejected POST /tests/{id}/reopensolo funciona en testsrejectedGET /tests/{id}/timelineretorna 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=redcuando el test está enred_executing - Blue Team solo puede subir evidencias
team=bluecuando el test está enblue_evaluating - Admin puede subir en cualquier momento
Validación:
- Un
red_techpuede subir evidencia conteam=reden estadored_executing - Un
red_techNO puede subir evidencia conteam=blue - Un
blue_techpuede subir evidencia conteam=blueen estadoblue_evaluating - Un
blue_techNO puede subir evidencia conteam=red GET /tests/{id}/evidence?team=redfiltra correctamenteDELETE /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, customplatform: windows, linux, macosseverity: low, medium, high, criticalmitre_technique_id: filtrar por técnicasearch: búsqueda por nombre/descripción
Validación:
GET /test-templatesretorna lista paginadaGET /test-templates?source=atomic_red_teamfiltra por fuenteGET /test-templates?platform=windowsfiltra por plataformaGET /test-templates/by-technique/T1059.001retorna templates para esa técnicaPOST /test-templatessolo accesible por adminDELETE /test-templates/{id}hace soft delete (is_active=False)- El filtro
searchbusca 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-testsejecuta 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:
// 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<string, unknown>;
}
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 endpointsfrontend/src/api/evidence.ts— actualizar con parámetroteamfrontend/src/api/test-templates.ts— nuevo
Funciones nuevas en tests.ts:
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:
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:
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
uploadEvidenceincluye el campoteamen FormDatagetTestEvidencesenvía el query paramteamcorrectamente
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"
- Red Tech en
- 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_executingpara 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_evaluatingpara 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:
- El usuario selecciona un template (desde el catálogo o desde la vista de técnica)
- Se abre un formulario pre-rellenado con los datos del template
- El usuario puede modificar los campos
- 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
draftored_executingcreados por mí - Blue Tech: tests en
blue_evaluating - Red Lead: tests en
in_reviewpendientes de validación red - Blue Lead: tests en
in_reviewpendientes de validación blue
- Red Tech: tests en
- 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 endpointsbackend/app/schemas/metrics.py— añadir nuevos schemasfrontend/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:
- Pipeline de Tests: gráfico de funnel mostrando cuántos tests hay en cada estado
- Actividad por equipo: Red Team vs Blue Team — tests completados, tiempo medio
- Tasa de validación: porcentaje de aprobación por Red Lead y Blue Lead
- 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:
- Importar Atomic Red Team: botón para ejecutar importación, con progreso y resultado
- Estadísticas del catálogo: total templates, por fuente, por plataforma
- Crear template personalizado: formulario inline o modal
- 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:
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.pyejecuta 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:
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.pypasa 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:
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.pypasa 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:
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 losblue_tech - Cuando un test pasa a
in_review→ notificar ared_leadyblue_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_countretorna 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.pyfrontend/src/api/notifications.tsfrontend/src/components/NotificationBell.tsxfrontend/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 conteoNotificationDropdown: 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 camposbackend/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.pyfrontend/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 rutasfrontend/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:
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.pypasa 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 funcionalidadesdocs/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 y adaptadas al contexto de Aegis:
- Tests mapeados a MITRE ATT&CK: Cada test está directamente vinculado a una técnica, igual que Validato mapea simulaciones a TTPs.
- 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.
- 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.
- Resultados mapeados a frameworks: Los resultados se mapean de vuelta a MITRE ATT&CK para actualizar la cobertura.
- Remediación paso a paso: Inspirado en cómo Validato proporciona remediation steps, cada test puede incluir pasos de remediación sugeridos.
- Validación continua: El pipeline draft → red → blue → review → validated permite re-ejecutar tests continuamente para medir mejoras.
- Reportes de cobertura: Exportación de reportes para demostrar compliance (similar a los reportes de Validato para DORA, NIS2, GLBA).
- Priorización por severidad: Los templates incluyen severidad para priorizar qué tests ejecutar primero.