Columnas sensibles.
Marca las columnas que guardan datos personales o de pago y decide qué pasa con cada query que las lee: bloquearla, marcarla o enmascarar el valor. Esta página dice qué garantiza cada modo de conexión, y qué no.
Resumen
Bloquear un DELETE destructivo protege los datos del agente. No hace nada contra el riesgo contrario: un agente que lee lo que no debería. SELECT email, card_number FROM customers es inofensivo para la base de datos y aun así pone datos personales y de pago en el contexto de un LLM.
Con las columnas sensibles, marcas columnas por base de datos desde el dashboard y Vericto decide sobre el AST de cada query, igual que con cualquier otra regla: la misma query recibe siempre la misma decisión, sin leer nunca los resultados y sin latencia añadida. El audit trail dice qué columna disparó cada decisión.
Disponibilidad. Planes Team y Enterprise. Las etiquetas se guardan, se sincronizan con tus proxies y se muestran en el dashboard desde ya; se aplican cuando estén desplegadas las versiones del proxy TCP y del evaluador de Vericto que las soportan. Mientras tanto, el dashboard indica que todavía no se aplican.
Políticas
Cada columna marcada tiene una política. Si una query lee varias columnas marcadas, gana la más estricta: block > mask > flag. Todas se reportan con la regla VERICTO-085.
- block: la query que lee la columna se bloquea.
- flag: la query pasa y queda registrada, con alerta.
- mask: la proyección se reescribe para devolver el valor enmascarado. Solo Postgres por ahora; en MySQL y los demás dialectos una etiqueta
maskbloquea la query.
| Estilo | Resultado | Expresión en Postgres |
|---|---|---|
full | [redacted] | '[redacted]'::text |
last4 | **** y los últimos 4 caracteres | '****' || "right"(col::text, 4) |
email | La primera letra y el dominio: a***@example.com. Un valor sin @ también se enmascara: p*** | regexp_replace(col::text, '^(.)[^@]*(@.*)?$', E'\\1***\\2') |
hash | SHA-256 en hexadecimal | encode(sha256(convert_to(col::text, 'UTF8')), 'hex') |
Una columna enmascarada se devuelve como texto. Una columna numérica o de fecha con last4 o hash cambia de tipo: el dashboard lo advierte y propone full para nombres que no parecen texto. Cualquier expresión calculada sobre una columna enmascarada (lower(email), substring(card, 1, 4)) se enmascara con full, sea cual sea el estilo.
Qué cuenta como lectura
Vericto sigue de qué columnas deriva cada expresión proyectada, en cualquier nivel de subquery o CTE. Un alias, una función, una agregación o un CASE sobre la columna siguen siendo una lectura de la columna.
SELECT *,t.*, las referencias a la fila completa (to_jsonb(t),row_to_json(t)) yCOPY … TOsobre una tabla con columnas marcadas se bloquean bajomaskyblock, y se marcan bajoflag. El mensaje pide listar las columnas.- Una columna que solo aparece en
WHERE,JOIN,GROUP BYuORDER BYno es una lectura: no se devuelve nada. - Copiar el valor a otro sitio (
INSERT … SELECT,CREATE TABLE … AS,UPDATE … SET x = email) cuenta como lectura; bajomaskse bloquea, porque enmascarar cambiaría los datos guardados. - Un nombre de tabla sin esquema que podría ser una tabla marcada se trata como la tabla marcada. Ante la duda, la columna se considera sensible: un falso positivo es una query bloqueada con un mensaje claro; un falso negativo es una fuga.
La garantía en cada modo
La garantía depende de quién ejecuta la query. Solo el proxy TCP está entre la query y la base de datos; en los demás modos Vericto devuelve una decisión y otro la ejecuta.
| Modo | Quién ejecuta | block | mask | flag | ¿Se aplica? |
|---|---|---|---|---|---|
| Proxy TCP | El proxy, en línea | Error nativo de la base de datos, como hoy | El proxy envía el SQL reescrito; la base de datos devuelve el valor ya enmascarado | Pasa, queda registrada | Sí: el cliente no tiene otro camino a la base de datos |
| API de runtime | La aplicación, después de preguntar | BLOCKED, como hoy | La respuesta incluye rewritten_query; la aplicación debe ejecutarla | Pasa, marcada (FLAGGED) | No: una aplicación que ignora la respuesta ejecuta la original |
| MCP | El agente, con su propia herramienta de base de datos | Bloqueada con el motivo | La query enmascarada se devuelve como la única aprobada | Aviso | No: depende de que el agente la siga |
| CLI / API de validación | Nadie (CI, migraciones) | Falla el pipeline | No aplica; la versión enmascarada se muestra como sugerencia | Aviso en el reporte | No hace falta: el control es que el cambio nunca llegue a producción |
El enmascaramiento es un control en el proxy TCP y una recomendación en los demás modos. Un agente no «no puede» leer una columna salvo que llegue a la base de datos a través del proxy.
Cómo marcar columnas
En Bases de datos, cada base tiene la sección Columnas sensibles: el esquema (opcional), la tabla, la columna, la política y, para mask, el estilo. Los nombres se comparan sin distinguir mayúsculas. Marcar, cambiar y quitar etiquetas es del owner y los admins; el resto del equipo las ve.
Sugerencias. Vericto nunca se conecta a tu base de datos, así que no conoce tu esquema. Las sugerencias salen del tráfico reciente: columnas que tus queries leyeron y cuyo nombre se parece a un dato sensible (email, card, ssn, password, token, iban, phone…). Se marcan con un clic, pero decides tú.
Los cambios llegan a cada proxy en su siguiente sincronización de reglas, sin reiniciar, y la API los usa en la siguiente evaluación. Con al menos una etiqueta block o mask, una query que no se puede analizar se bloquea: no se puede demostrar que no lea una columna marcada.
Audit trail
Cada block, mask y flag es un evento del audit trail con la regla VERICTO-085, la base de datos y la columna que lo disparó. Cuando una query se enmascaró, el evento guarda la query original y la reescrita, cifradas igual que cualquier query.
Marcar o quitar una columna cambia lo que un agente puede leer, así que cada cambio queda en el registro de auditoría del workspace, con quién lo hizo y la política antes y después.
Arquitectura recomendada para agentes
Para que el enmascaramiento sea un control y no una recomendación:
- El agente llama a una herramienta, una API tuya, mejor con operaciones de negocio (
get_order(id)) que con «ejecuta este SQL». Nunca tiene credenciales de base de datos. - Esa API llega a la base de datos solo a través de un proxy de Vericto.
- La base de datos solo acepta conexiones del proxy en ese camino (security group o firewall).
- Un proxy dedicado para el camino del agente, registrado como su propia base de datos con el enmascaramiento activo. La política es por base de datos, así que una aplicación que debe mostrar emails reales a personas usa otra instancia.
- El agente no tiene otro camino a los datos: ni otro servidor MCP de base de datos ni credenciales en su entorno.
Límites
- Es defensa en profundidad: los privilegios de columna, las vistas y el row-level security de tu base de datos siguen siendo la primera línea.
- Vericto decide por el nombre de la columna, no por su contenido: no busca datos sensibles en los valores.
- Los ORMs que hacen
SELECT *se bloquean bajomaskhasta que listen las columnas. - Si renombras una columna, su etiqueta deja de aplicarse: márcala de nuevo con el nombre nuevo.