Las migraciones SQL son el último lugar donde quieres una sorpresa
Migraciones generadas por LLMs
Tu agente escribió la migración. ¿Agregó una cláusula WHERE? ¿Acotó el UPDATE? ¿Evitó TRUNCATE? No lo sabes hasta que se ejecuta.
El review manual no escala
Con 10 deploys al día, nadie lee cada migración con atención. Un WHERE faltante a las 3am y estás haciendo un restore de emergencia.
Producción es demasiado tarde
Detectar un DELETE FROM orders en staging es suerte. Detectarlo en CI es ingeniería.
Así se ve el CLI de Vetro en tu pipeline
$ vetro check --file migrations/0042_cleanup.sql --dialect postgres Vetro — Deterministic SQL Firewall v1.0.0 Evaluating 4 queries against workspace ruleset... ✓ Line 3: ALTER TABLE users ADD COLUMN last_seen_at TIMESTAMPTZ ALLOWED ✓ Line 8: CREATE INDEX idx_users_last_seen ON users(last_seen_at) ALLOWED ✗ Line 14: DELETE FROM audit_logs BLOCKED Rule: VETRO-001 — DELETE without WHERE clause AST node: DeleteStmt > WhereClause = NULL Severity: CRITICAL Fix: DELETE FROM audit_logs WHERE created_at < NOW() - INTERVAL '90 days' ✓ Line 19: UPDATE users SET last_seen_at = NOW() WHERE user_id = $1 ALLOWED Summary: 3 passed, 1 blocked Exit code: 1
Tu pipeline falla en este paso. La migración nunca llega a staging.
Un paso para agregar a tu workflow de GitHub Actions
name: CI
on: [push, pull_request]
jobs:
sql-safety:
name: SQL Safety Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Vetro CLI
run: npm install -g @vetro/cli
- name: Check SQL migrations
env:
VETRO_API_KEY: ${{ secrets.VETRO_API_KEY }}
run: |
vetro check \
--file migrations/ \
--dialect postgres \
--workspace ${{ vars.VETRO_WORKSPACE_ID }}
La VETRO_API_KEY es una API key de workspace (vtro_...) con el scope ci_dryrun:execute. Créala en tu dashboard de Vetro bajo API Keys.
Equivalente para GitLab CI
sql-safety:
stage: validate
image: node:20-alpine
script:
- npm install -g @vetro/cli
- vetro check --file migrations/ --dialect postgres
variables:
VETRO_API_KEY: $VETRO_API_KEY
VETRO_WORKSPACE_ID: $VETRO_WORKSPACE_ID
Cada archivo, cada query, cada regla
El CLI de Vetro envía cada sentencia SQL de tu archivo al mismo motor AST que protege tu base de datos en producción. Las mismas reglas, la misma lógica, cero drift entre CI y producción.
Soporta
-
Archivos
.sqlindividuales -
Directorios de archivos
.sql(recursivo) - SQL piped por stdin
-
Múltiples dialectos:
postgres,mysql,oracle,mssql
Reporta
- Decisión por query (ALLOWED / BLOCKED)
- Código de regla y ruta del nodo AST
- Fix sugerido por query bloqueada
- Exit code para integración CI
-
Output JSON para tooling personalizado (
--format json)
Por qué "shift left" en SQL security importa
10x
más barato detectar un bug en CI que en producción (NIST, 2024)
4.2h
tiempo promedio de recuperación tras un incidente por query destructiva (equipo de 3 seniors)
$0
costo de una migración bloqueada en CI vs pérdida de datos, tiempo de restore e impacto en clientes
El modo dry-run de CI/CD está disponible en el plan Team ($149/mes). El plan Free y el plan Builder no incluyen acceso al CLI.
Pasar al plan Team →Preguntas frecuentes
-
No. El modo dry-run evalúa el SQL contra el ruleset definido en tu workspace, pero nunca se conecta a ninguna base de datos. Es un paso de análisis estático puro.
-
Sí, pero sin una API key de workspace el CLI usa el ruleset por defecto (solo reglas CRITICAL). Para reglas personalizadas y la configuración de tu workspace, necesitas una cuenta Team.
-
Archivos
.sqlestándar, directorios (todos los archivos.sqlde forma recursiva), y stdin. Maneja archivos multi-sentencia, comentarios y bloques procedurales. -
Sí. Usa
--min-severity criticalpara fallar solo en reglas CRITICAL. Los hallazgos de severidad MEDIUM (como SELECT sin LIMIT) se reportan pero no fallan el build.