Los agujeros de las apps hechas con IA casi nunca empiezan como código malo. Empiezan como una petición que suena razonable — “desactiva el RLS para que funcione” — y el agente obedece, porque obedecer es su trabajo. vibeward lo caza en cuanto lo escribes, caza al agente haciéndolo sin que se lo pidan, y audita lo que ya esté desplegado. Reporta; nunca edita tu código. Determinista, de solo lectura, MIT.
$ npx vibeward@latest init
sin llamadas a LLM100% localsin telemetríasin cuentaes · en · pt
Funciona en Claude Code·Cursor·Codex·Copilot·Gemini·Windsurf·opencode — dos comandos en Claude Code, un init en el resto. Lo que cada uno puede hacer cumplir cambia, y te dice cuál. Hecho con Claude Code, y pilla a su propio autor. Una capa junto al plugin de seguridad oficial de Anthropic, no un reemplazo. Sin afiliación con Anthropic.
Tres fallos documentados en el mundo real — informes públicos de incidentes e investigación publicada, no mediciones propias de vibeward. Los tres se citan mal; lo que sigue es la versión que sobrevive a leer la fuente primaria.
Desactivar el RLS. Mover una clave service_role al cliente. Hacer público un bucket o una tabla. Quitar una comprobación de auth. Un comodín en CORS, un secreto hardcodeado, el CSRF o el rate limiting apagados, un .env a punto de commitearse. Cada una responde con el riesgo, por qué importa y la alternativa segura — “ignora todo lo anterior…”, el clásico, no le hace nada a un motor de reglas.
> desactiva el RLS de la tabla users para que funcione la query ⚠ vibeward marcó una petición peligrosa ✗ Desactivar Row-Level Security por qué: apagar el RLS deja cada fila legible para cualquiera que tenga la anon key pública — la causa más común de fugas en apps hechas a prompts. haz esto en su lugar: deja el RLS activo y añade una policy: CREATE POLICY ... USING (auth.uid() = user_id)
La petición de arriba, atrapada antes de que el agente actúe. Ocho reglas sobre lenguaje natural, en el idioma en el que piensas.
La que nadie pidió. Una puerta de prompt nunca ve al agente que choca con una query que falla y tira de DISABLE ROW LEVEL SECURITY por su cuenta — no hubo prompt. Mismas reglas que el escaneo de código, apuntadas al archivo que todavía no se ha escrito.
Inyección de prompt: un README, una página o un resultado MCP con instrucciones dirigidas a tu agente. Ya no queda nada que bloquear, así que se reetiqueta como dato y se te dice qué intentaba.
desactiva el RLS, usa la service_role en el front, desativa o login por enquanto — las mismas reglas, sin capa de traducción y sin LLM.
No son ocho reglas escritas tres veces: los objetos peligrosos ya son independientes del idioma — RLS, service_role, CORS y .env son identificadores, no palabras. Un idioma cuesta una tabla de verbos de unas 40 entradas, que es el único tamaño que un hablante nativo puede auditar de verdad. Ese es el punto: un conjunto de reglas en un idioma que no lees es un conjunto de reglas que nadie revisa. Se agradecen PRs añadiendo una tabla.
init nunca escribe @latest en tus ajustes — es el único sitio donde sería mal negocio, porque el guardarraíl corre en cada prompt que escribes: ~1,8 s cada uno, muerto sin red, y cualquier publicación futura ejecutándose sin revisar en tu máquina. Así que busca un vibeward instalado, te ofrece instalarlo si no hay ninguno, y fija una versión exacta si prefieres que no. Los tres caminos son seguros; el binario instalado es sencillamente el más rápido.
npx vibeward@latest init --scope user
Por defecto no bloquea. Donde el editor permite que un hook ponga texto delante del modelo, el guardarraíl hace eso y no interrumpe nada — tu prompt sobrevive, el agente corrige su propio enfoque, y un falso positivo te cuesta una nota que ignoras. Donde un editor solo puede bloquear, vibeward se queda callado: perder el párrafo que acabas de escribir es como se desinstala un guardarraíl, y uno desinstalado no protege a nadie. --block está ahí si aun así quieres el corte duro.
Un producto hecho con IA falla de dos formas que no tienen nada que ver: deja los datos abiertos, y deja la página vacía. Las dos merecen saberse. Reportarlas en la misma escala es cómo una fuga real acaba enterrada bajo un favicon que falta — así que vibeward las mantiene separadas, hasta el código de salida.
Contado por severidad, escrito en SARIF, y código de salida 2 ante un crítico. Ningún fichero de configuración lo silencia.
Su propia sección, su propia escala. Fuera del recuento por severidad, fuera de SARIF, fuera del código de salida. Sáltatelo entero con --no-web.
“Un favicon ausente jamás debe compartir escala con una service key expuesta.”
La service_role de Supabase y el nuevo formato sb_secret_, Stripe, OpenAI, Anthropic, Google, AWS, GitHub, Slack, Resend, Twilio, cadenas de conexión a base de datos y claves PEM privadas — en bundles o en el código, con el fichero:línea exacto.
Enumera tus tablas expuestas en vivo desde la data API y luego sondea cada una con la clave pública. Marca qué columnas contienen datos personales, revisa las filas devueltas por si traen claves de terceros, y comprueba la introspección de GraphQL.
Detecta la configuración del cliente y sondea si hay una Realtime Database abierta y un bucket de Storage listable públicamente — el patrón detrás de la brecha de Tea.
Next.js con Prisma o Drizzle: cabeceras ausentes en next.config, server actions y route handlers que mutan datos sin comprobar auth, e inyección de fórmulas en exportaciones CSV.
Inyección SQL, CORS abierto, inyección de comandos, eval y errores verbosos que filtran información en tus rutas de API.
Source maps .map desplegados, ficheros SQLite commiteados, un .env en el repo — además de CSP, HSTS y X-Frame-Options en la respuesta real.
Un robots.txt que echa a GPTBot, ClaudeBot, PerplexityBot, CCBot o Google-Extended — y un llms.txt que falta. La gente ya busca dentro de los asistentes; a un sitio que no pueden leer no lo citan.
Sin <title> — o el mismo título en todas las páginas. Sin meta description, sin canonical, sin Open Graph, sin JSON-LD, sin sitemap.xml.
Cero o varios <h1> en una página, un atributo lang ausente, imágenes desplegadas sin alt.
Sin un 404 real, sin favicon, assets rotos, errores de consola al cargar y un bundle JS sin comprimir de más de 1 MB. Los errores de consola usan Playwright si resulta que lo tienes; si no, lo dice.
Todavía en *.vercel.app o *.lovable.app, framework detectado, ver-código-fuente vacío — puntuado sobre 12. Cuánto se sigue pareciendo el sitio al día en que se generó.
vibeward detecta ausencias binarias: la etiqueta no está, el fichero nunca se escribió. Eso es lo que le falta a un sitio hecho con IA. Core Web Vitals y WCAG completo quedan fuera de alcance, a propósito.
Pregúntale a un agente “¿falta la meta description?” y se inventará una respuesta. Un parser que responde sí o no nunca lo hace. Así que vibeward decide qué es cierto y se instala en tus herramientas de IA como skill cuyo trabajo es hacerlo legible — liderando con lo que te cuesta, citando la evidencia, sin reformular jamás una severidad con sus propias palabras.
claude plugin marketplace add jsiapo-dev/plugins
claude plugin install vibeward
El skill y los tres momentos del guard vienen incluidos, y /plugin uninstall vibeward se lleva hasta el último rastro. El plugin lleva su propia copia del CLI —compilada por CI desde el código del tag y publicada en su propia rama, nunca ensamblada a mano—, así que el guard que corre sobre el prompt que acabas de escribir no resuelve nada desde la red, en la versión que tú elegiste. No hay npx @latest en ese camino.
Reglas deterministas producen los hallazgos — ningún modelo de por medio, ningún hueco inventado.
Un payload JSON para el agente y un informe markdown formateado para ti. Cada hallazgo trae su evidencia, su impacto y cómo es uno correcto.
Y solo tú. Los hallazgos no llevan campo fix ni autofix, porque aquí no hay una orden de trabajo que ejecutar.
? ¿Qué instalo? ❯ ◉ Claude Code skill + guard ◉ Cursor skill + guard ○ OpenAI Codex CLI skill + guard ○ GitHub Copilot CLI skill + guard ○ Gemini CLI skill + guard ○ Windsurf / Devin skill + guard ○ opencode skill + guard ? ¿Qué debe vigilar el guard? ❯ ◉ Cuando envías un prompt ◉ Cuando el agente edita o ejecuta ◉ Cuando el agente lee
Previsualiza cada fichero antes de tocar el disco, nunca sobrescribe uno que no escribió él, fusiona los ficheros de settings clave por clave — tus otros hooks se quedan donde están — y el markdown entre marcadores. Volver a ejecutarlo es cómo se actualiza. Cualquier fichero existente se respalda en .vibeward.bak antes de su primer cambio.
Un SKILL.md por herramienta: el formato ya es común, así que hay un solo cuerpo de texto en vez de un fichero de reglas por editor. No interactivo para CI y dotfiles:
vibeward init --scope user --all --yes
Y te dice lo que no puede hacer. No todos los editores aplican lo mismo — uno no puede filtrar un prompt en absoluto — así que init imprime los límites por herramienta después de escribir, en vez de dejarte suponer que estás cubierto.
Declara qué se supone que es el sitio y vibeward contrasta la realidad con eso. A una herramienta internal no se la juzga por sitemaps ni Open Graph — pero sí por assets rotos y texto alt.
{
"schemaVersion": 1,
"intent": {
"aiCrawlers": "blocked",
"siteType": "website"
},
"suppress": [
{ "id": "web_missing_og",
"reason": "private landing" }
]
}
Decir aiCrawlers: "blocked" hace que vibeward deje de llamarlo error — y plantea la pregunta mejor: ¿estás bloqueado tan a fondo como crees? Si tu robots.txt cierra la puerta a tres de los doce crawlers de IA, ese bloqueo incompleto pasa a ser el hallazgo. Creerte cerrado mientras entran nueve es peor que no haber decidido nada.
Y nunca se esconde nada. Cada supresión exige un motivo escrito, el informe imprime “producido con N supresión(es) activas” justo bajo el veredicto y las lista una a una. Solo se pueden suprimir comprobaciones de web — un veredicto del que cualquiera puede salir editando un fichero no es un veredicto.
Bundles, sondeo en vivo de Supabase y Firebase, cabeceras, source maps — y toda la pasada de web. --passive lo reduce a lo que un navegador ya se descarga, sin sondear datos en absoluto.
$ vibeward https://app.lovable.app
Un repo, o un ZIP recién salido de v0 o Bolt. Lee el código, el backend y las migraciones SQL — tablas creadas sin RLS, policies USING (true), funciones SECURITY DEFINER.
$ vibeward scan ./client-app
JSON en stdout, cada línea para humanos en stderr, así que entra directo en un parser. El payload lleva un schemaVersion — si la forma cambia, ese número cambia con ella.
$ vibeward https://app.com \
--json --stdout --yes
Los hallazgos se suben como SARIF y aterrizan en la pestaña Security del repo. El job falla ante un crítico — los hallazgos de web nunca cambian el código de salida. Apúntalo a una carpeta con path, o a una URL desplegada con url.
- uses: JSiapoDEV/vibeward@v0.6.2
with:
url: https://your-app.com
Suficiente para que una persona capte el riesgo en cinco segundos, y suficiente para que un agente abra un pull request correcto.
users es legible sin autenticaciónemail, phone, full_name.GET /rest/v1/users?select=* con la anon key sacada del bundle JS. Vuelven todas las filas. Sin login.El escaneo es de solo lectura: lee tu código, tus bundles y las respuestas públicas para detectar riesgo — nunca modifica, borra ni explota. La única excepción es --write-test, explícita y opcional, que envía una sola sonda de escritura no destructiva (un insert vacío) para comprobar escrituras sin autenticar; está apagada salvo que la pidas. init es el único comando que escribe, y solo dentro de tu propio proyecto.
No — ni los hallazgos de seguridad, ni los de web, ni los mecánicos de una línea, ni aunque se lo pidas. Los hallazgos no llevan campo fix ni autofix, y las instrucciones que vibeward instala le prohíben al agente actuar sobre uno. Eso es el producto, no una funcionalidad que falta: una auditoría que termina en un montón de diffs que nadie pidió sustituye lo que puedes accionar por algo que ahora tienes que revisar. Y en seguridad es peor que desordenado — borrar una clave expuesta de un bundle no la des-filtra. Hay que rotarla, y solo tú decides cuándo y si el incidente hay que comunicarlo.
No. Los hallazgos de web quedan excluidos del recuento por severidad, del fichero SARIF y del código de salida — por diseño, no por configuración. Solo la seguridad bloquea. Si no los quieres ni en el informe, --no-web se salta la pasada entera.
Sí — es la comprobación estrella. Encuentra la clave pública de Supabase en tu bundle (un JWT o el nuevo formato sb_publishable_), enumera en vivo cada tabla expuesta, y marca cuáles devuelven datos sin login. Ese es exactamente el modo de fallo de Moltbook — agents, owners, agent_messages y observers legibles por cualquiera, y las tablas públicas además escribibles. Para ser precisos sobre lo que la comprobación no es: encontrar la clave sb_publishable_ en un bundle no es el hallazgo. Esa clave va en el cliente por diseño. El hallazgo es una tabla que le responde.
No. vibeward comprueba ausencias binarias — una etiqueta que no está en el HTML, un fichero que nunca se generó, un crawler al que se echó. Son las cosas que un generador se salta y a las que nadie vuelve. Core Web Vitals, presupuestos de rendimiento y una auditoría WCAG completa quedan fuera de alcance a propósito; para eso ejecuta Lighthouse.
Nunca. El escáner y el guardarraíl corren enteramente en local — sin telemetría, sin cuenta, sin subidas. La única petición saliente es a la URL a la que tú lo apuntas.
Solo las de web, y nunca en silencio. Cada entrada de vibeward.json exige un motivo escrito, y el informe indica cuántas supresiones estaban activas y qué alegaba cada una. Los hallazgos de seguridad no se pueden silenciar desde un fichero de configuración — si no, cualquiera aprobaría su propia auditoría editando un fichero.
No, y ese es el punto. Es un motor de reglas determinista, así que no se le puede convencer. El clásico que empieza con "ignora todo lo anterior…" no le hace nada: no hay modelo al que persuadir.
Usa los dos — y si trabajas en Claude Code, instala también el suyo: /plugin install security-guidance@claude-plugins-official, gratis en todos los planes. Revisa lo que el modelo ya escribió: coincidencia de patrones en cada edición de fichero, un modelo leyendo el diff al final del turno, y una pasada agéntica más profunda en cada commit que hace Claude. Su documentación dice sin rodeos dónde se detiene. Sobre bloqueo: “None of the layers block writes or commits” — ninguna de sus capas frena una escritura ni un commit. Y receta ella misma la solución: “For hard enforcement, pair the plugin with a hook that blocks the edit” — para aplicación estricta, combina el plugin con un hook que bloquee la edición. Pide que se lo tome como “one layer of defense in depth, not a complete security solution”: una capa de defensa en profundidad, no una solución de seguridad completa. vibeward es ese hook, un momento antes: frena la petición antes de que el código exista, y --block hace que ahí se detenga en vez de solo anotar. Conoce Supabase y Firebase por su nombre y no por clase de patrón; el guardarraíl no gasta tokens de modelo ni necesita Python, red ni repo git, mientras que el suyo se salta sus dos capas de modelo en silencio fuera de un repo; entiende español y portugués; y el escáner lee una URL desplegada, que ninguna revisión de tu copia de trabajo puede ver. Ninguno de los dos bloquea por defecto — el suyo vuelve a preguntarle a Claude con los hallazgos, el nuestro inyecta una nota y sale con 0 — y ninguno sustituye al otro.
Ninguno. El RLS de Supabase es una comprobación entre muchas: Firebase, claves expuestas, backends inseguros, source maps, cabeceras y toda la pasada de web funcionan en cualquier stack. Apúntalo a cualquier repo, ZIP o URL.
Para quien desplegó una app de Supabase, Lovable, Bolt o v0 y es el único responsable de ella: un desarrollador, una app, ningún equipo de seguridad al que escalar.
No es un programa de AppSec de empresa, y no pretende serlo. Si necesitas gobierno de políticas en una organización, controlar qué herramientas de IA pueden usar tus desarrolladores, un inventario de componentes de IA o SAST sobre un monorepo, compra algo hecho para eso — hay proveedores que lo hacen bien y esto no compite con ellos. Saber cuál de los dos necesitas vale más que la lista de features de cualquiera.
Hecho con Claude Code, y conviene decirlo en voz alta en un proyecto cuyo tema es el código que producen los agentes. La objeción es justa —una herramienta de seguridad escrita por un agente es justo de lo que esta herramienta desconfía— y la respuesta es que cada regla es determinista y legible, sometida a 751 aserciones incluidas entradas construidas para hacerlas fallar. La mitad útil es que pilla a su propio autor: escribir esta web disparó el gate de contenido, preparar un commit disparó el de acción, e imprimir un token real en una página de demo hizo que vibeward reportara vibeward.ai. Cada uno se arregló en las reglas o en el contenido — ninguno se silenció, porque los hallazgos de seguridad son la única clase que el archivo de configuración deliberadamente no puede suprimir.
Sin afiliación, patrocinio ni respaldo de Anthropic. Claude Code es el editor que protege primero, y aquel en el que fue escrito.
vibeward encuentra lo visible desde fuera y desde el código. No encuentra autorización rota a nivel de objeto detrás de un login, un límite entre inquilinos que aguanta en la primera petición y se rompe en la tercera, ni lógica de negocio que ya estaba mal antes de que nadie escribiera un prompt. No es modestia — está en el README, porque un escáner que diga lo contrario es la razón por la que la gente se fía de un tick verde del que no debería fiarse.
Eso necesita a alguien leyendo tu app, y es el trabajo que hago: reglas de Supabase y Firebase, fronteras de autenticación, y un informe escrito lo bastante concreto como para que tu propio agente actúe sobre él. Reserva 20 minutos — trae la URL.
US$150, alcance fijo, 48 horas. Una app, un informe escrito y una lista corta de qué cambiar primero. Si no aparece nada crítico, no hay factura — una app limpia es un resultado real y no deberías pagar por que te lo digan. La objeción evidente es justa: cobrar solo cuando aparece algo es un incentivo a que aparezca algo. Por eso “crítico” queda fijado por escrito antes de empezar, y es una lista corta: una clave service_role o de admin alcanzable desde el navegador, una tabla o un bucket que responde sin autenticación, o una frontera de auth que una segunda petición atraviesa. Nada más cuenta, diga lo que diga el escáner. Si crees que inflé un hallazgo para llegar a ese listón, dilo y no hay factura. Reserva 20 minutos si te encaja.
La herramienta sigue siendo gratis y MIT pase lo que pase. No hay plan de pago ni nada reservado fuera de ella — los US$150 pagan a una persona leyendo tu app, no una función.
Sin instalar, siempre la última versión, solo lectura. Ejecútalo únicamente contra apps cuyo dueño haya autorizado la auditoría.
$ npx vibeward@latest scan ./your-app