Ir al contenido

Redacción de PII

La redacción ocurre en el borde del runner, después de que el connector responde y antes de que el resultado cruce la frontera. Un único punto de aplicación: ni disperso ni repetido del otro lado.

Está activa cuando RUNNER_CONNECTORS=real. En el camino sintético los datos no llevan PII, así que solo corre la capa de campo declarado.

Enmascara las rutas que el manifest del connector declara en sensitiveFields. Es dot-path puro, por diseño.

Una pasada indexada por operación, para las formas que una regex no ve: valores arbitrarios de property bags e identificadores crudos de usuario final.

Cubre exactamente cinco operaciones de Amplitude:

Operación Enmascara Redacta
analytics.searchUser userId properties
analytics.getUserActivity ninguno properties, deviceId
replays.listSessionReplays userId ninguno
replays.getSessionReplay userId ninguno
replays.getSessionReplayEvents ninguno properties

En las property bags, las claves se conservan y los valores se redactan, y la forma de los datos sigue legible para el diagnóstico, el contenido no.

Para cualquier otra operación, esta capa es un no-op.

Una pasada final por regex, sensible al contenido, sobre las cadenas que hayan quedado: email, CPF, IPv4, tarjeta de crédito con validación de Luhn y números de teléfono, más un conjunto de nombres de campo sensibles.

No se guía por dot-path, así que complementa las dos capas anteriores y funciona como defensa en profundidad.

Qué más sale del Agent, y cómo se redacta

Sección titulada «Qué más sale del Agent, y cómo se redacta»

El resultado de una operación no es el único dato que cruza la frontera. Estos son todos los canales, y por lo que pasa cada uno:

Canal Redacción
Resultado y error de operación Las tres capas.
detail del probe de credenciales, que llega a la Flota Las mismas tres capas, por el mismo redactor, antes de truncar el mensaje.
Advertencias del recolector de una captura que salió bien, y el motivo de una captura que falló (el stderr del recolector y del agregador), que llegan a la pantalla de Profiling Las tres capas, por el mismo redactor. Las advertencias se cortan a 400 caracteres y 20 entradas después de la redacción.
Learned-state (topología, registros DNS, rutas de load balancer) El motor de contenido, al salir del Agent, con una excepción para IPs, descrita abajo.
Firma del Profiler Ninguna. Lleva símbolos de código y peers de red, y lo que sale está listado en Profiler.

Una IP de infraestructura no es PII; una IP en texto libre sí. En un resultado, la capa de contenido enmascara toda IPv4, porque en un texto arbitrario no puede distinguir la dirección de un cliente de la de un servidor. El learned-state sí puede: un registro DNS es configuración de tu infraestructura, y la IP dentro de él (el destino de un registro A, el frontend de un load balancer, un ip4: de SPF) es la dirección de un recurso tuyo, y es lo que responde “¿en qué servicio cae esta dirección?”. Por eso una IP pasa solo dentro del nombre y del destino de un registro DNS, y en cualquier otro campo del learned-state se enmascara como en un resultado. Es la misma línea que la capa de contenido ya traza para los bloques CIDR. Emails, CPFs, tarjetas y números de teléfono se redactan en cualquier campo, incluso dentro de un registro DNS: el rua=mailto: de un registro DMARC sale como [EMAIL].

Esta es la trampa que más a menudo produce una garantía falsa, así que vamos al grano.

FieldRedactor es dot-path puro. Declarar en el manifest un campo que solo existe dentro de un array (por ejemplo, un campo de un RumErrorSample[]) no redacta nada. Y eso es peor que no declararlo, porque produce la apariencia de una garantía que no existe.

Para ese caso, la regla va en redactStructured, que está indexado por operación y sí cruza arrays.

Ventana de terminal
WHYSTACK_PII_REDACTION=off

Hay un alias legado, INFRAINTEL_PII_REDACTION. Cuando ambos están presentes, gana el nombre nuevo.

Sé preciso sobre su alcance:

Capa Con WHYSTACK_PII_REDACTION=off
1. Campo declarado sigue corriendo
2. Estructural desactivada
3. Contenido desactivada

El kill switch vale para todos los canales de la tabla de arriba que pasan por la capa de contenido, incluido el learned-state.

Con las capas desactivadas no hay redacción que auditar, así que el rastro no es una línea de auditoría. Hay otros tres:

  • En producción, el Agent se niega a arrancar. Con off, RUNNER_CONNECTORS=real y NODE_ENV=production (el valor de la imagen), el boot falla nombrando la variable.
  • Fuera de eso, arranca con una advertencia en el log de boot.
  • Y anuncia el estado al control-plane cuando se conecta, y la Flota muestra el Agent como corriendo sin redacción.

Clasificación divergente: el borde expone, no reescribe

Sección titulada «Clasificación divergente: el borde expone, no reescribe»

Un caso que aparece en la práctica y que conviene entender antes de reportarlo como bug.

Datadog manda todo stderr a status:error. Así que una búsqueda de errores puede devolver [INFO] Worker exiting. La fuente lo clasificó como error, el texto dice otra cosa.

El borde expone la divergencia en lugar de reescribir el campo: junto al level de la fuente, emite textLevel y levelMismatch. El principio es que la clasificación de la fuente es un hecho sobre la fuente, y corregirla en silencio borraría información.

Qué Dónde
La composición de las tres capas apps/runner/src/redact/pii-redactor.ts
Capa de campo declarado apps/runner/src/redact/field-redactor.ts
Capa estructural, por operación packages/core-edge/src/policy/structured-redactor.ts
Motor de contenido packages/core-edge/src/policy/pii-redactor.ts
Kill switch packages/core-edge/src/policy/kill-switch.ts, y el rechazo en el boot en apps/runner/src/boot.ts
Learned-state al salir del Agent apps/runner/src/learned/redact.ts
detail del probe de credenciales apps/runner/src/connectors/health.ts
Advertencias del recolector y motivo de una captura fallida apps/runner/src/profiling/push.ts