Your coding agents' security, in one command.
Rules followed, dangerous actions blocked, code fixed before the commit, and every agent visible to your team.
npx -y @cybedefend/vibedefend@latest installEU or US region, chosen at install. The guard decides on your machine.
8 times fewer broken rules.
Your rules, served before each edit.
Business rules learned from your code and security rules for your stack, picked for the file it edits.
Claude Code is writing
billing/refund.tsasync function refund(order, amount) { if (amount > 500) await approvals.second(order); await payments.refund(order, amount); return receipt(order); }
Refunds above €500 need a second approver.
Approved once by Sofia M.Written with your rule, before the edit lands.
Dangerous commands never run.
Schema drops, sudo, secret reads and force pushes are refused; the agent is told why and takes another way.
OpenAI Codex wants to run
rm -rf ./storage/uploads
- Read
- Checked against your guards
- Refused
- Run
Blocked: protected path, user uploads
Fixed before the commit.
When the agent finishes, its changes are scanned and it fixes each finding. Your project's findings are in its session.
SQL injection, reachable
CWE-89, src/db/users.repo.ts:42"SELECT * FROM users WHERE id = $1", [id]Fixed by the agent before the commit
Then proved, not assumed.
After the commit, BLSA checks its business logic and proves each verdict: the rule, the path, the line.
Refunds above €500 need a second approver.BLSA, proof mode
POST /refundsEntry point
approvals.second(order)The rule's check
payments.refund(order)Runs after the check
Holds: approved before it is paid
Everything it does, on one map.
Every rule served, every refusal and every fix, traced to its agent and its developer in the Brain.
Cursorsrc/billing/cart-checkout.ts3 rules served
DROP TABLE invoices;Blocked
CWE-89, src/db/users.repo.ts:42Finding fixed
Traced to Sofia M., in the Brain
Nobody told your agent. Now it knows.
One command. Every agent. No card.
npx -y @cybedefend/vibedefend@latest installIn detail
Then proved, not assumed.
After the commit, BLSA (Business Logic Security Analysis, built with the CNRS and the CRIStAL laboratory) checks the business logic of the change, and its proof mode shows why each verdict holds or breaks: the rule, the path through the code, the line. BLSA is open to design partners today.
The eight business-logic flaws it prevents
of API vulnerabilities exploit business logic, not a known CVE.
Wallarm, API ThreatStats 2026
Multi-tenant leaktenant scoping on queriesCWE-639
Lookup by id with no tenant filter: any signed-in customer can read this order.
before
// GET /api/orders/:id const order = await db.order.findUnique({ where: { id: req.params.id }, }); return res.json(order);
after
// GET /api/orders/:id const order = await db.order.findUnique({ where: { id: req.params.id, tenantId: req.user.tenantId }, }); if (!order) return res.status(404).end(); return res.json(order);
Rule: tenant scoping on queries
Refund bypassauthorization ceiling on refundsCWE-840
Refund created with no role check and no ceiling: any amount goes out on any intent.
before
router.post('/refund', async (req, res) => { await stripe.refunds.create({ payment_intent: req.body.intent, amount: req.body.amount, }); return res.json({ ok: true }); });
after
router.post('/refund', requireRole('finance'), async (req, res) => { const intent = await getOwnedIntent(req.user, req.body.intent); const amount = clampRefund(intent, req.body.amount); await stripe.refunds.create({ payment_intent: intent.id, amount }); return res.json({ ok: true }); });
Rule: authorization ceiling on refunds
Missing idempotencyidempotency key on webhooksCWE-837
No idempotency key: the same Stripe event replayed credits the order twice.
before
app.post('/webhook/stripe', async (req, res) => { await orders.markPaid(req.body.id); await ledger.append({ type: 'charge', ... }); res.send('ok'); });
after
app.post('/webhook/stripe', async (req, res) => { const key = req.headers['idempotency-key']; if (await seen.has(key)) return res.send('dup'); await orders.markPaid(req.body.id); await ledger.append({ type: 'charge', key, ... }); await seen.add(key, '24h'); res.send('ok'); });
Rule: idempotency key on webhooks
PII in logsPII policy in logsCWE-532
The whole req.body goes to the logs: email and password in cleartext at your log vendor.
before
logger.info('signup', { user: req.body });
after
logger.info('signup', { userId: hash(req.body.email), region: req.body.region, });
Rule: PII policy in logs
Auth middleware skippedmandatory auth middleware on routesCWE-306
Route mounted without the auth middleware: /admin/users is reachable with no session.
before
// public.routes.ts router.get('/admin/users', listAllUsers);
after
// admin.routes.ts (auth + rbac applied at mount) router.use(requireSession, requireRole('admin')); router.get('/users', listAllUsers);
Rule: mandatory auth middleware on routes
Feature flag rolloutsecure feature-flag defaultsCWE-1188
Missing flag defaults to true: the export switches itself on in production.
before
if (flags.allow_anyone_to_export ?? true) { return exportAll(); }
after
if (flags.allow_anyone_to_export === true && req.user.role === 'admin') { audit.log('export.all', req.user); return exportAll(); }
Rule: secure feature-flag defaults
Rate limit absentrate limiting on loginCWE-307
No attempt limit on /login: credential bruteforce is unlimited.
before
router.post('/login', loginHandler);
after
router.post('/login', rateLimit({ windowMs: 60_000, max: 8, keyGenerator: ipAndEmail }), loginHandler);
Rule: rate limiting on login
Tenant-wide exporttenant scoping on admin exportsCWE-285
findMany with no tenant scope: the CSV export returns every customer's users.
before
router.get('/admin/export', requireAdmin, async (_req, res) => { const rows = await db.user.findMany({}); res.csv(rows); });
after
router.get('/admin/export', requireAdmin, async (req, res) => { const rows = await db.user.findMany({ where: { tenantId: req.user.tenantId }, }); audit.log('export', req.user); res.csv(rows); });
Rule: tenant scoping on admin exports
Four layers, one install.
Rules served
Business rules mined from your code, plus your security rules, served before each edit.
Claude Code is writing
src/billing/cart-checkout.ts
const total = new Decimal128(cart.sum); const rows = await db.query( "SELECT * FROM carts WHERE id = $1", [id] );
Monetary amounts use Decimal128, never Number.
Mined from src/billing.ts:14Parameterise every query that mixes user input.
OWASP Top 10Served before the edit
Secret guard
Raw secret reads are refused; the agent gets the managed reference instead.
Cursorwebhooks.ts
cat .env | grep STRIPEBlocked: raw secret read
Instead
process.env.STRIPE_WEBHOOK_SECRETnpm test -- webhooksTests pass
Logged for the team
Action guard
Destructive commands, schema drops and protected paths are stopped before they run.
OpenAI Codex
rm -rf dist/Allowed: build output
rm -rf .cache/Allowed: cache
rm -rf ./storage/uploadsBlocked: protected path, user uploads
Logged for the team
Live findings
SAST, SCA, secrets, IaC and CI/CD findings, live in the session for the agent to fix.
GitHub Copilot
SAST
src/db/users.repo.ts:42SQL injection
SCA
package.jsonlodash 4.17.20, CVE-2021-23337
Secrets
config/prod.ymlAWS access key
IaC
infra/main.tfS3 bucket public-read
CI/CD
.github/workflows/deploy.ymlpull_request_target
In the agent's context, live
Your frameworks, served as rules.
The security rules the agent receives map to the frameworks your auditors check.
- OWASP Top 10
- SOC 2
- GDPR
- ISO 27001
Try it free on your own code.
No card. To go further, we run a pilot with your team and set the price with you.
Before you install.
In CybeDefend's controlled study of 24 August 2026, the same agent applied 89% of precise rules with VibeDefend, against 12% with no tool and 13% with a rules file kept by hand.