Patrones DLP personalizados
Define reglas de detección específicas para tu organización que se ejecutan sobre la cobertura integrada de PII, credenciales y datos financieros de ShieldAgent.
Qué son los patrones personalizados
Los patrones DLP personalizados permiten a tu equipo definir reglas adicionales de detección de datos sensibles específicas para tu organización — por ejemplo, códigos internos de proyectos, identificadores propietarios o formatos de datos específicos del dominio. Cada patrón es una expresión regular compatible con RE2 asociada a una acción (bloquear, redactar, alertar o modo sombra). Los patrones personalizados se evalúan en secuencia después de las reglas integradas, de modo que amplían la cobertura estándar en lugar de reemplazarla.
Comparación de planes
Los límites de patrones personalizados y las funciones de flujo de trabajo dependen de tu plan de ShieldAgent.
| Funcionalidad | Pro | Business |
|---|---|---|
| Máximo de patrones personalizados | 20 | 20 |
| Acciones disponibles | bloquear, redactar, alertar | bloquear, redactar, alertar |
| Aprobación de activación | Aprobador único | 4 ojos (requiere dos aprobadores) |
| Entrega de webhook al detectar | — | Sí, firmado con HMAC |
Límites de sintaxis RE2
Los patrones deben ser expresiones RE2 válidas. No se admiten los siguientes elementos:
- Referencias inversas (\1, \2, …)
- Aserciones de anticipación y retrospectiva
- Recursividad basada en referencias inversas
- Cuantificadores posesivos de PCRE
El tamaño máximo del patrón compilado es de 256 KB. Los patrones excesivamente amplios (p. ej., .* sin anclajes) se rechazan al guardar.
Prueba antes de desplegar
Usa el endpoint de ejecución en seco para validar un patrón contra tráfico de muestra antes de activarlo. Las ejecuciones en seco evalúan el patrón sobre hasta 50 payloads recientes de llamadas a herramientas capturadas en modo sombra. No se toma ninguna acción — los resultados se devuelven inmediatamente.
- Abre el panel, ve a Seguridad → DLP → Patrones personalizados y selecciona Nuevo patrón.
- Introduce tu expresión RE2 y elige una acción.
- Haz clic en Probar patrón para ejecutar una prueba en seco sobre el tráfico reciente en modo sombra.
- Revisa los extractos coincidentes (los valores están parcialmente enmascarados) y ajusta el patrón si es necesario.
- Haz clic en Guardar para enviar el patrón a activación (sujeto a aprobación en planes Business).
Ejecución en seco mediante SDK
También puedes ejecutar pruebas en seco de forma programática:
const result = await client.dlp.patterns.dryRun({
expression: '\\bPROJ-[0-9]{4,6}\\b',
action: 'alert',
sampleSize: 50,
});
// result.matches — array of masked excerpts
// result.matchCount — total hits across sampled payloads
console.log(`Matched ${result.matchCount} times across ${result.sampleSize} payloads`);Opciones de acción
Cada patrón personalizado está asociado a una de cinco acciones:
| Acción | Cuándo usarla |
|---|---|
| bloquear | Rechaza la llamada a la herramienta inmediatamente. Úsalo para patrones que nunca deben salir de tu perímetro. |
| redactar | Reemplaza el valor coincidente con un token de redacción y reenvía la solicitud saneada. Úsalo cuando la herramienta destino aún necesita recibir la solicitud pero no debe ver el valor sensible. |
| alertar | Permite la solicitud y genera un evento de auditoría. Úsalo para supervisión cuando el bloqueo interrumpiría un flujo de trabajo que todavía estás evaluando. |
| notify | Permite la solicitud y envía un webhook firmado o un evento de Slack a tu endpoint configurado (Business). En Pro, escribe una notificación en la aplicación. No se transmite el contenido de la coincidencia — solo un hash SHA-256. |
| sombra | Registra la coincidencia de forma silenciosa sin modificación ni alerta al agente. Solo en el plan Business. Úsalo durante el despliegue para validar la precisión del patrón antes de cambiar a una acción más agresiva. |
Aprobación de 4 ojos (Business)
En los planes Business, cualquier patrón personalizado nuevo o modificado entra en estado pendiente antes de estar activo. Un segundo aprobador designado — distinto del autor del patrón — debe revisarlo y aprobarlo. Esto evita que un solo administrador active un patrón demasiado amplio o incorrecto de forma unilateral.
Entrega de webhook
Cuando un patrón personalizado con la acción notify coincide en un plan Business, ShieldAgent envía un evento firmado a tu endpoint configurado. Cada entrega incluye una firma HMAC usando tu secreto de webhook. No se transmite el contenido de la coincidencia — solo un hash SHA-256.
Esquema del payload del webhook
{
"event": "dlp.notify",
"version": 1,
"patternId": "550e8400-e29b-41d4-a716-446655440000",
"patternName": "internal-project-codes",
"action": "notify",
"actionTaken": "notify",
"tenantId": "550e8400-e29b-41d4-a716-446655440001",
"agentId": "550e8400-e29b-41d4-a716-446655440002",
"mcpServerId": "550e8400-e29b-41d4-a716-446655440003",
"interactionId": "550e8400-e29b-41d4-a716-446655440004",
"contentHashSha256": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3",
"contentHash": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3",
"severity": "high",
"gdprClassification": "credential",
"timestamp": "2026-05-30T14:22:00.000Z"
}Referencia de campos
| Campo | Tipo | Nulable | Ejemplo | Descripción |
|---|---|---|---|---|
| event | string | no | "dlp.notify" | Siempre "dlp.notify". Úsalo para enrutar el evento en tu receptor. |
| version | number | no | 1 | Versión del esquema. Se incrementa ante cambios incompatibles. Versión actual: 1. |
| patternId | string (UUID) | no | "550e8400-…" | ID del patrón personalizado que desencadenó este evento. |
| patternName | string | no | "internal-project-codes" | Nombre del patrón tal como está configurado en tu panel. |
| action | string | no | "notify" | Siempre "notify" en este payload. |
| actionTaken | string | no | "notify" | Alias de action. Incluido para simetría de esquema con otros tipos de eventos. |
| tenantId | string (UUID) | no | "550e8400-…" | Identificador de tu espacio de trabajo en ShieldAgent. |
| agentId | string (UUID) | no | "550e8400-…" | Sesión de agente que realizó la llamada a la herramienta. |
| mcpServerId | string (UUID) | no | "550e8400-…" | El servidor MCP al que se enrutó la llamada. |
| interactionId | string (UUID) | no | "550e8400-…" | Único por interacción de llamada a herramienta. Úsalo como clave de idempotencia — los reintentos llevan el mismo ID. |
| contentHashSha256 | string (hex) | no | "a665a459…" | Hash SHA-256 del texto coincidente. El valor sin procesar nunca se transmite. |
| contentHash | string (hex) | no | "a665a459…" | Alias de contentHashSha256. |
| severity | "critical" | "high" | "medium" | "low" | no | "high" | Gravedad según la clasificación del patrón. |
| gdprClassification | "pii" | "credential" | "financial" | "health" | "none" | no | "credential" | Categoría de datos RGPD del contenido detectado. |
| timestamp | string (ISO 8601) | no | "2026-05-30T14:22:00.000Z" | Marca de tiempo UTC en que se generó el evento. |
Verificación HMAC
La firma se envía en el encabezado X-ShieldAgent-Signature como sha256=<hex>. Verifícala siempre antes de procesar el evento. Usa una comparación en tiempo constante para prevenir ataques de temporización:
Node.js
import crypto from 'node:crypto';
export function verifySignature(rawBody: string, secret: string, header: string): boolean {
if (!header.startsWith('sha256=')) return false;
const expected =
'sha256=' +
crypto.createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex');
const a = Buffer.from(expected, 'utf8');
const b = Buffer.from(header, 'utf8');
if (a.length !== b.length) return false;
return crypto.timingSafeEqual(a, b);
}
// Express: capture the raw body before JSON parsing
// app.use('/shieldagent-notify', express.raw({ type: 'application/json' }));
// app.post('/shieldagent-notify', (req, res) => {
// if (!verifySignature(req.body.toString('utf8'), process.env.SHIELDAGENT_WEBHOOK_SECRET!, req.header('x-shieldagent-signature')!)) {
// return res.status(401).end();
// }
// const payload = JSON.parse(req.body.toString('utf8'));
// res.status(200).json({ ok: true });
// });Python
import hmac, hashlib
def verify_signature(raw_body: bytes, secret: str, header: str | None) -> bool:
if not header or not header.startswith('sha256='):
return False
expected = 'sha256=' + hmac.new(
secret.encode('utf-8'), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, header)
# FastAPI example:
# @app.post('/shieldagent-notify')
# async def handle(request: Request):
# raw = await request.body()
# if not verify_signature(raw, os.environ['SHIELDAGENT_WEBHOOK_SECRET'],
# request.headers.get('x-shieldagent-signature')):
# raise HTTPException(401)
# payload = json.loads(raw)Vector de prueba
Ejecuta tu verificador con estos valores antes de pasar a producción. Cualquier diferencia significa que tu implementación es incompatible con la ruta de firma de producción:
secret = "shieldagent-test-secret-32ch-pad"
body = '{"event":"dlp.notify","version":1,"hash":"deadbeef"}'
header = "sha256=8834a0520425c5b374ab3d444d3c0368cb6eb1af1a1678a2ed5e8937e8bcb06f"Gestiona y rota tu secreto de webhook en Panel → Seguridad → DLP → Destinos de notificación. Las firmas antiguas se invalidan inmediatamente al rotar.
Esquema del payload de Slack
Cuando tu destino de notificación es un webhook entrante de Slack, ShieldAgent envía un mensaje Block Kit en lugar del payload JSON canónico. El encabezado X-ShieldAgent-Signature sigue presente y se calcula sobre los bytes del cuerpo Block Kit, no sobre el payload canónico. Si tu receptor de Slack también verifica la firma, calcula el hash del cuerpo de la solicitud exactamente tal como se recibe.
Ejemplo Block Kit
{
"text": ":warning: ShieldAgent DLP notify: `internal-project-codes` (high)",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":warning: ShieldAgent DLP notify: `internal-project-codes` (high)"
}
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*Pattern*\ninternal-project-codes" },
{ "type": "mrkdwn", "text": "*GDPR class*\ncredential" },
{ "type": "mrkdwn", "text": "*Agent*\n`550e8400-e29b-41d4-a716-446655440002`" },
{ "type": "mrkdwn", "text": "*MCP server*\n`550e8400-e29b-41d4-a716-446655440003`" },
{ "type": "mrkdwn", "text": "*Interaction*\n`550e8400-e29b-41d4-a716-446655440004`" },
{ "type": "mrkdwn", "text": "*Content SHA-256*\n`a665a45920422f9d…`" }
]
},
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "event=dlp.notify version=1 ts=2026-05-30T14:22:00.000Z" }
]
}
],
"metadata": {
"event_type": "dlp.notify",
"event_payload": { "...": "full canonical payload — same fields as webhook schema above" }
}
}Campos de nivel superior
| Campo | Tipo | Descripción |
|---|---|---|
| text | string | Resumen en texto plano que se muestra en las notificaciones de Slack y en las vistas previas de enlaces. |
| blocks | array | Secciones Block Kit: encabezado de resumen, sección de campos con nombre del patrón, clase RGPD, agente, servidor MCP, ID de interacción y prefijo del hash de contenido, más un pie de contexto con metadatos del evento. |
| metadata.event_type | "dlp.notify" | Tipo de evento estructurado para la ingesta en SIEM. |
| metadata.event_payload | object | Payload canónico completo de DLP notify (los mismos campos que el esquema del webhook anterior). Permite que las herramientas SIEM indexen campos estructurados desde un evento entregado por Slack. |
¿Qué ocurre si pego una URL de Slack en un destino webhook genérico?
La API reconoce las URLs de webhooks entrantes de Slack y corrige automáticamente el tipo de destino de webhook a slack. La llamada de creación o actualización se ejecuta correctamente, y la respuesta incluye dos campos adicionales:
| Campo de respuesta | Tipo | Descripción |
|---|---|---|
| autoCorrectedToSlack | boolean | true cuando el tipo se cambió automáticamente de webhook a slack. |
| warnings | string[] | Contiene "url_resembles_chat_platform_consider_dedicated_kind" cuando la URL fue corregida automáticamente. |
Si configuras kind: webhook con una URL que se asemeja a Discord o Microsoft Teams, la API devuelve la misma advertencia sin corregir automáticamente — el destino se guarda como webhook y la entrega puede fallar. Establece el tipo correcto de forma explícita al crear el destino.