Reglas Custom.
Define condiciones AST determinísticas propias para bloquear queries específicas de tu stack — sin IA, sin varianza estocástica.
¿Qué son las reglas custom?
Las reglas estándar de Vetro cubren los patrones destructivos más comunes (DELETE sin WHERE, DROP TABLE, TRUNCATE, etc.). Las reglas custom permiten extender ese ruleset con condiciones específicas de tu negocio, definidas mediante una condición YAML sobre el árbol sintáctico AST de la query.
Como todas las reglas de Vetro, las custom son determinísticas: el mismo input produce siempre el mismo resultado. No hay modelos de ML, no hay varianza. Una query cumple la condición o no la cumple — sin ambigüedad.
Ejemplos de uso habitual:
- Bloquear
SELECT *en tablas de pagos o usuarios (evita exfiltración masiva de datos) - Prevenir
UPDATEsin cláusula WHERE en tablas de alta criticidad - Detectar llamadas a funciones peligrosas como
SLEEP()oPG_SLEEP() - Bloquear queries que acceden a esquemas internos (
information_schema,pg_catalog) - Forzar el uso de índices en columnas específicas (prohibir queries sin predicado)
Disponibilidad por plan
Las reglas custom están disponibles desde el plan BUILDER ($49/mes).
| Plan | Reglas custom | Límite |
|---|---|---|
| Free | No disponible | — |
| Builder ($49/mes) | ✅ Incluido | Hasta 50 reglas custom |
| Team ($149/mes) | ✅ Incluido | Ilimitadas |
Si intentas crear una regla custom en el plan Free, la API responde con 403 Payment Required y un link de upgrade.
Esquema YAML
Cada regla custom lleva una condición YAML que define cuándo Vetro debe bloquear una query. El YAML debe tener al menos los campos rule y node_type.
rule: nombre-interno-de-la-regla # identificador libre
node_type: DeleteStmt # tipo de nodo AST a capturar
condition:
where_clause: null # solo si falta WHERE
Campos del YAML
Identificador interno de la regla. Aparece en los logs y el audit trail. Usa kebab-case, ej: block-select-star-payments.
Tipo de nodo del AST que activa la condición. Ver tipos de nodo disponibles.
Predicados adicionales sobre el nodo. Si se omite, la regla se dispara para todo nodo del node_type indicado. Ver condiciones disponibles.
Mensaje personalizado que se incluye en la respuesta de bloqueo y en el audit trail. Máx. 256 caracteres.
Tipos de nodo AST
Los nodos del AST representan el tipo de sentencia o expresión SQL que Vetro detecta en el árbol sintáctico. El dialecto determina qué parser se usa (pg_query para PostgreSQL, sqlparser-rs para MySQL).
| node_type | Descripción | Dialecto |
|---|---|---|
DeleteStmt | Sentencia DELETE | postgres / all |
UpdateStmt | Sentencia UPDATE | postgres / all |
SelectStmt | Sentencia SELECT | postgres / all |
InsertStmt | Sentencia INSERT | postgres / all |
DropStmt | Sentencia DROP (TABLE, DATABASE, INDEX, SCHEMA) | postgres / all |
TruncateStmt | Sentencia TRUNCATE | postgres |
AlterTableStmt | ALTER TABLE (DROP COLUMN, RENAME, etc.) | postgres |
FuncCall | Llamada a función SQL (SLEEP, PG_SLEEP, etc.) | postgres / all |
Condiciones disponibles
Dentro de condition: puedes usar los siguientes predicados según el tipo de nodo:
Para DELETE / UPDATE / SELECT
| Predicado | Valor | Significado |
|---|---|---|
where_clause: null | null | La query NO tiene cláusula WHERE |
where_always_true: true | true | WHERE trivialmente verdadero (1=1, true) |
Para SELECT
| Predicado | Valor | Significado |
|---|---|---|
target_list: "*" | "*" | La query usa SELECT * |
has_limit: false | false | La query no incluye LIMIT |
Para FuncCall
| Predicado | Valor | Significado |
|---|---|---|
func_name: "nombre" | string | Nombre de la función a bloquear (case-insensitive) |
Para DropStmt
| Predicado | Valor | Significado |
|---|---|---|
object_type: "table" | "table", "schema", "index" | Tipo de objeto que se está eliminando |
Ejemplos prácticos
1. Bloquear SELECT * (exfiltración masiva)
rule: block-select-star
node_type: SelectStmt
condition:
target_list: "*"
Bloquea queries como SELECT * FROM users o SELECT * FROM payments. Permite queries con columnas explícitas como SELECT id, email FROM users.
2. Bloquear UPDATE sin WHERE
rule: block-update-no-where
node_type: UpdateStmt
condition:
where_clause: null
Bloquea UPDATE users SET status = 'blocked' pero permite UPDATE users SET status = 'blocked' WHERE id = $1.
3. Detectar tautologías SQL injection
rule: block-or-tautology
node_type: DeleteStmt
condition:
where_always_true: true
Bloquea queries como DELETE FROM users WHERE id = 1 OR 1=1 detectando el branch OR trivialmente verdadero en el AST.
4. Bloquear llamadas a SLEEP (DoS)
rule: block-sleep-calls
node_type: FuncCall
condition:
func_name: sleep
Bloquea SELECT SLEEP(10) (MySQL) y SELECT PG_SLEEP(10) (PostgreSQL) para prevenir ataques de Denial of Service.
5. Bloquear SELECT sin LIMIT
rule: require-limit-on-select
node_type: SelectStmt
condition:
has_limit: false
message: "Las queries SELECT deben incluir cláusula LIMIT para evitar scans completos de tabla"
Útil para tablas muy grandes donde un full scan sin límite puede degradar el rendimiento significativamente.
6. Bloquear DROP de cualquier objeto
rule: block-all-drops
node_type: DropStmt
Sin condition:, la regla se dispara para cualquier DROP (TABLE, INDEX, SCHEMA). Útil en entornos de producción donde ningún DROP debe ejecutarse desde la aplicación.
Previsualización antes de activar
Antes de guardar una regla custom, el dashboard ofrece una previsualización que evalúa el YAML contra las queries históricas del workspace de los últimos 7 días.
La previsualización muestra:
- Si el YAML es válido (
validation_result.valid: true/false) - Cuántas queries históricas hubiera bloqueado esta regla
- Un ejemplo de query que dispara la condición
- Lista de eventos del audit trail que coinciden
La previsualización es solo de lectura — no bloquea nada. La regla solo empieza a bloquear queries en tiempo real cuando haces clic en Crear regla.
API REST para reglas custom
Crear una regla custom
POST /api/v1/workspaces/:workspace_id/rules/custom
Authorization: Bearer <token>
{
"name": "Bloquear SELECT * en pagos",
"severity": "warning",
"dialect": "postgres",
"ast_condition_yaml": "rule: block-select-star\nnode_type: SelectStmt\ncondition:\n target_list: \"*\""
}
// Response 201
{
"rule_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"code": "CUSTOM-001",
"name": "Bloquear SELECT * en pagos",
"severity": "warning",
"is_active": true,
"created_at": "2025-06-20T10:00:00Z",
"validation_result": { "valid": true, "errors": [] }
}
Previsualizar antes de guardar
POST /api/v1/workspaces/:workspace_id/rules/custom/preview
Authorization: Bearer <token>
{
"ast_condition_yaml": "rule: block-select-star\nnode_type: SelectStmt\ncondition:\n target_list: \"*\"",
"dialect": "postgres",
"lookback_days": 7
}
// Response 200
{
"matching_queries": [...],
"total_matches": 3,
"validation_result": { "valid": true, "errors": [] },
"example_triggering_query": "SELECT * FROM users"
}
Campos requeridos
| Campo | Tipo | Descripción |
|---|---|---|
name | string (1–128 chars) | Nombre descriptivo de la regla |
severity | "critical" / "warning" / "info" | Severidad — determina si dispara alertas |
dialect | "postgres" / "mysql" / "all" | Dialecto SQL al que aplica la regla |
ast_condition_yaml | string YAML (10–16384 chars) | Condición AST que define cuándo bloquear |
Limitaciones actuales
- Las condiciones YAML solo soportan los predicados documentados arriba — no se puede escribir expresiones arbitrarias sobre el AST todavía.
- El campo
condition.table_name(filtrar por nombre de tabla específica) está en roadmap pero no disponible aún. - Máximo 50 reglas custom en plan Builder, ilimitadas en plan Team.
- El YAML se valida en el servidor — un YAML sintácticamente incorrecto devuelve
400 Bad Requestcon los errores de validación. - Las reglas custom no soportan CTE data-modifying todavía (ej:
WITH x AS (DELETE ...)). Las reglas estándar VETRO-001 a VETRO-020 sí las detectan.
Usa siempre la previsualización antes de activar una regla custom en producción. Una regla mal configurada puede bloquear queries legítimas. El equipo de Vetro recomienda activar primero en staging y validar durante 24h antes de pasar a producción.
¿Tienes un caso de uso que las condiciones actuales no cubren? Escríbenos — los casos reales de clientes guían el roadmap de nuevos predicados.