# Inspección y DLP

> Qué peticiones de salida de un job de CI revisa Egress CI en busca de secretos, qué cambia inspect y el compromiso de terminar TLS dentro de un job.

Egress CI revisa lo que envía un job en busca de secretos con los detectores de fugas de datos de la pasarela [OpenWAF Egress](https://developers.openwaf.dev/es/egress/#what-it-detects). En enforce, una petición que lleva uno se rechaza; en audit pasa y el resumen lista la detección.

## Qué se detecta

| Id de detección | Qué |
|---|---|
| `dlp.private_key` | Una clave privada PEM (`-----BEGIN … PRIVATE KEY-----`) |
| `dlp.aws_access_key` | Un id de clave de acceso de AWS |
| `dlp.openai_key` | Una clave `sk-` al estilo de OpenAI |
| `dlp.github_token` | Un token de GitHub, salvo cuando va a GitHub (`github.com`, `githubusercontent.com`, `ghcr.io`, `githubapp.com` y sus subdominios), donde se espera el token del propio job |
| `dlp.credit_card` | Un número de tarjeta de pago que pasa la comprobación de Luhn |
| `dns.high_entropy_label` | Una etiqueta DNS de 40 caracteres o más con mucha entropía: datos codificados en un nombre |
| `dns.long_name` | Un nombre de 150 caracteres o más |
| `tls.sni_mismatch` | Un `CONNECT` cuyo SNI de TLS nombra un host fuera de la política |

Las detecciones `dns.` se marcan, pero no se rechazan por sí solas: el nombre se responde o se rechaza según la política. Un secreto dentro de un nombre DNS o del host de un `CONNECT` (`dlp.…` sobre el nombre) se detecta en cualquier destino, porque el nombre se ve sin descifrar nada.

## Qué se revisa

| Petición | Qué se revisa |
|---|---|
| HTTP en claro por `HTTPS_PROXY`/`HTTP_PROXY` | URL, cabeceras y cuerpo |
| HTTP en claro capturado por el bloqueo (una herramienta que ignora el proxy) | Los primeros bytes de la conexión: línea de petición, cabeceras y el principio del cuerpo |
| HTTPS a un host de `inspect`, por `HTTPS_PROXY` | URL, cabeceras y cuerpo de cada petición |
| Cualquier otro HTTPS | Solo el nombre (host del `CONNECT`, SNI, nombre DNS), no el contenido |

Los cuerpos se revisan enteros hasta 4 MiB. Los más grandes, y los binarios (`application/octet-stream`, `image/*`, `video/*`, zip, gzip, tar), pasan sin revisar, y el evento lo indica.

## inspect

```yaml
allow:
  - api.staging.example.com
inspect:
  - api.staging.example.com
```

Para un host de `inspect`, el proxy termina el TLS del job con un certificado emitido por una CA creada para la ejecución, revisa cada petición y la reenvía por una conexión TLS nueva al host real, cuyo certificado verifica como siempre. La inspección funciona en HTTP/1.1 (el proxy solo ofrece `http/1.1` en ALPN) y en las conexiones hechas por `HTTPS_PROXY`; una herramienta que ignora las variables de proxy llega al host por el proxy transparente, que comprueba el nombre pero no descifra.

Para que el job confíe en la CA de la ejecución, la acción escribe su certificado en `$RUNNER_TEMP/egress-ci/ca.pem` y un bundle con las CA del sistema, y deja estas variables:

| Variable | La leen |
|---|---|
| `NODE_EXTRA_CA_CERTS` | Node.js |
| `SSL_CERT_FILE` | Las herramientas basadas en OpenSSL, Go, Ruby, el módulo `ssl` de Python |
| `REQUESTS_CA_BUNDLE` | Python Requests |
| `CURL_CA_BUNDLE` | curl |
| `GIT_SSL_CAINFO` | Git |

## El compromiso del TLS

Inspeccionar significa que el job acepta una CA capaz de firmar un certificado para cualquier nombre mientras dura la ejecución. La acción limita lo que eso cuesta:

- La CA se crea al principio de cada ejecución, vale 12 horas y solo para esa ejecución. Su clave privada nunca sale de la memoria del sidecar; solo se escribe el certificado.
- Solo firma certificados para los hosts de `inspect`; cualquier otra conexión HTTPS sigue siendo un túnel opaco.
- El sidecar sigue verificando el certificado del host real, así que inspeccionar no te oculta un certificado malo: la petición falla.

Y lo que no resuelve:

- Las herramientas con su propio almacén de confianza (el `cacerts` de una JVM, algunos gestores de paquetes) o con pinning de certificados fallan en los hosts inspeccionados. Deja esos hosts fuera de `inspect`.
- Los contenedores no reciben las variables; la inspección es para los pasos del propio job.
- Sin `inspect`, el contenido de las peticiones HTTPS no se ve nunca. Un secreto enviado por HTTPS a un host permitido no se detecta: la lista de permitidos es el control principal, y el DLP es una segunda línea para el HTTP en claro y para los hosts que elijas inspeccionar.

Inspecciona los hosts donde un secreto en un cuerpo importaría y a los que tus herramientas llegan por el proxy: una API de staging a la que tus tests hacen POST, un webhook, un endpoint de artefactos o de telemetría. No inspecciones los registries ni GitHub.
