Files
Aegis/AegisTestPlan_v2.md

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:

  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:

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:

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:

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:

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:

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:

{
  "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:

// 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 endpoints
  • frontend/src/api/evidence.ts — actualizar con parámetro team
  • frontend/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
  • 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:

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:

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:

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:

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:

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 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.