API REST (Desarrolladores)
Brechas de Seguridad

Brechas de Seguridad

Endpoints para gestionar incidentes de seguridad y brechas de datos personales en DPOLab.

Todos los endpoints requieren autenticacion JWT, excepto el webhook de Wazuh que usa autenticacion HMAC-SHA256.

Listar incidentes

GET /api/v1/breaches

Query params:

ParamTipoDescripcion
pagenumberPagina (default: 1)
limitnumberRegistros por pagina (default: 20)
statusstringFiltrar por estado: detected, investigating, contained, resolved, notified
requiresNotificationbooleanFiltrar por requerimiento de notificacion a la APDP

Ejemplo:

curl -X GET "https://api.dpolab.com/api/v1/breaches?status=investigating&requiresNotification=true" \
  -H "Authorization: Bearer {token}"

Respuesta (200):

{
  "success": true,
  "data": {
    "items": [
      {
        "id": "brch_abc123",
        "title": "Acceso no autorizado a base de datos de clientes",
        "status": "investigating",
        "detectedAt": "2026-03-08T03:15:00Z",
        "estimatedRecords": 1500,
        "notificationDeadlineAt": "2026-03-11T03:15:00Z",
        "requiresNotification": true,
        "createdAt": "2026-03-08T03:20:00Z"
      }
    ],
    "pagination": {
      "page": 1,
      "limit": 20,
      "total": 3,
      "totalPages": 1
    }
  }
}

Registrar incidente

POST /api/v1/breaches

Body:

{
  "title": "Acceso no autorizado a base de datos de clientes",
  "detectedAt": "2026-03-08T03:15:00Z",
  "detectionSource": "manual",
  "description": "Se detecto acceso no autorizado desde IP externa a la base de datos de produccion",
  "attackVector": "phishing",
  "dataCategories": ["name", "email", "rut", "phone"],
  "hasSensitiveData": true,
  "estimatedRecords": 1500,
  "containmentActions": ["Bloqueo de IP", "Rotacion de credenciales"]
}

Campos requeridos: title, detectedAt, detectionSource.

Respuesta (201):

{
  "success": true,
  "data": {
    "id": "brch_new456",
    "title": "Acceso no autorizado a base de datos de clientes",
    "status": "detected",
    "detectedAt": "2026-03-08T03:15:00Z",
    "createdAt": "2026-03-08T03:20:00Z"
  }
}

Obtener detalle del incidente

GET /api/v1/breaches/:id
curl -X GET https://api.dpolab.com/api/v1/breaches/brch_abc123 \
  -H "Authorization: Bearer {token}"

Respuesta (200):

{
  "success": true,
  "data": {
    "id": "brch_abc123",
    "title": "Acceso no autorizado a base de datos de clientes",
    "description": "Se detecto acceso no autorizado desde IP externa",
    "status": "investigating",
    "detectedAt": "2026-03-08T03:15:00Z",
    "detectionSource": "manual",
    "attackVector": "phishing",
    "dataCategories": ["name", "email", "rut", "phone"],
    "hasSensitiveData": true,
    "estimatedRecords": 1500,
    "containmentActions": ["Bloqueo de IP", "Rotacion de credenciales"],
    "requiresNotification": true,
    "notificationDeadlineAt": "2026-03-11T03:15:00Z",
    "notifiedApdpAt": null,
    "events": [
      {
        "type": "status_change",
        "from": "detected",
        "to": "investigating",
        "notes": "Inicio de investigacion",
        "createdAt": "2026-03-08T04:00:00Z"
      }
    ],
    "createdAt": "2026-03-08T03:20:00Z",
    "updatedAt": "2026-03-08T10:00:00Z"
  }
}

Actualizar incidente

PUT /api/v1/breaches/:id

Permite actualizar campos parciales del incidente.

curl -X PUT https://api.dpolab.com/api/v1/breaches/brch_abc123 \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "containmentActions": ["Bloqueo de IP", "Rotacion de credenciales", "Revision de logs"],
    "estimatedRecords": 2300
  }'

Cambiar estado del incidente

PATCH /api/v1/breaches/:id/status

Body:

{
  "status": "contained",
  "notes": "Se aislaron los sistemas afectados y se rotaron todas las credenciales."
}

Campos requeridos: status.

Ejemplo:

curl -X PATCH https://api.dpolab.com/api/v1/breaches/brch_abc123/status \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"status": "contained", "notes": "Sistemas aislados exitosamente."}'

Transiciones de estado permitidas

detected → investigating → contained → resolved
                                      → notified
EstadoDescripcion
detectedIncidente detectado, pendiente de investigacion
investigatingEn proceso de investigacion
containedIncidente contenido, impacto limitado
resolvedIncidente cerrado y resuelto
notifiedNotificado a la APDP y/o titulares

Arbol de decision de notificacion

POST /api/v1/breaches/:id/decision-tree

Evalua si el incidente requiere notificacion a la APDP y/o a los titulares afectados, segun los criterios de la Ley 21.719.

Body:

{
  "riskToSubjects": "high",
  "hasSensitiveData": true,
  "hasMinorData": false,
  "hasFinancialData": true
}

Campos requeridos: riskToSubjects, hasSensitiveData, hasMinorData, hasFinancialData.

Ejemplo:

curl -X POST https://api.dpolab.com/api/v1/breaches/brch_abc123/decision-tree \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"riskToSubjects": "high", "hasSensitiveData": true, "hasMinorData": false, "hasFinancialData": true}'

Respuesta (200):

{
  "success": true,
  "data": {
    "requiresNotification": true,
    "requiresSubjectNotification": true,
    "notificationDeadlineAt": "2026-03-11T03:15:00Z",
    "urgency": "high"
  }
}
⚠️

La Ley 21.719 (Art. 14 sexies) exige notificar a la APDP sin dilaciones indebidas desde que se conoce el incidente, pero no fija un plazo numérico. El plazo de 72 horas es del RGPD europeo (Art. 33), no de la ley chilena; DPOLab lo usa solo como objetivo interno de referencia. El incumplimiento del deber de reporte puede resultar en sanciones.

Notificar a la APDP

POST /api/v1/breaches/:id/notify-apdp

Registra la notificacion formal a la Agencia de Proteccion de Datos Personales.

Body:

{
  "notifiedAt": "2026-03-09T14:00:00Z",
  "notificationFileKey": "uploads/breach-notifications/brch_abc123.pdf"
}

Campos requeridos: notifiedAt, notificationFileKey.

Ejemplo:

curl -X POST https://api.dpolab.com/api/v1/breaches/brch_abc123/notify-apdp \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"notifiedAt": "2026-03-09T14:00:00Z", "notificationFileKey": "uploads/breach-notifications/brch_abc123.pdf"}'

Respuesta (200):

{
  "success": true,
  "data": {
    "notifiedAt": "2026-03-09T14:00:00Z",
    "notificationFileKey": "uploads/breach-notifications/brch_abc123.pdf",
    "status": "notified"
  }
}

Obtener plantilla de notificacion

GET /api/v1/breaches/:id/notification-template

Genera una plantilla de notificacion prellenada con los datos del incidente, lista para enviar a la APDP.

curl -X GET https://api.dpolab.com/api/v1/breaches/brch_abc123/notification-template \
  -H "Authorization: Bearer {token}"

Respuesta (200):

{
  "success": true,
  "data": {
    "template": "Senor/a Director/a\nAgencia de Proteccion de Datos Personales\n\nDe conformidad con lo establecido en el articulo 14 sexies de la Ley 21.719..."
  }
}

Webhook Wazuh

POST /api/v1/webhooks/wazuh/:tenantSlug

Endpoint para recibir alertas automaticas desde Wazuh SIEM. Crea incidentes automaticamente a partir de las alertas. El tenant se identifica por el parametro :tenantSlug en la URL.

Autenticacion: HMAC-SHA256 - Se valida la firma del payload usando un secreto compartido configurado en los settings del tenant.

Header requerido: X-Wazuh-Signature: sha256={hmac_signature}

curl -X POST https://api.dpolab.com/api/v1/webhooks/wazuh/mi-empresa \
  -H "Content-Type: application/json" \
  -H "X-Wazuh-Signature: sha256=abc123..." \
  -d '{
    "alert": {
      "rule": {
        "id": "100200",
        "description": "Multiple failed login attempts detected",
        "level": 12
      },
      "agent": {
        "name": "web-server-01"
      },
      "timestamp": "2026-03-09T02:30:00Z"
    }
  }'

Respuesta (201):

{
  "success": true,
  "data": {
    "breachId": "brch_auto789",
    "status": "detected",
    "detectionSource": "wazuh"
  }
}

Las alertas de Wazuh se clasifican automaticamente en severidad segun el level de la regla: 0-7 = low, 8-10 = medium, 11-13 = high, 14+ = critical.

Ver tambien