Skip to main content
Glama

๐Ÿ›ก๏ธ vibe-shield

The security gate for AI-written code.

Your agent ships fast. It also ships NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY, a DELETE route with no session check, and a CREATE TABLE with no Row Level Security โ€” because it was optimising for "it works".

vibe-shield is a static security scanner built for that failure mode, plus an Agent Skill that makes Claude Code, Codex, Cursor and Windsurf audit before they say "done".

npm version npm downloads CI node license zero dependencies rules self-scan

npx -y @vibefoundry/vibe-shield scan

vibe-shield terminal preview


v2.0.0: eight defensive vectors

The v2 catalogue covers client exposure; auth and route protection; database/RLS; AI and web sinks; infrastructure; dependency hygiene; secrets and cryptography; and agent/MCP integrity. The new hardening checks include production source maps, insecure JWT settings, explicit and omitted cookie flags, locally absent security headers, container users, lifecycle scripts, lockfiles and weak cryptography. Run rules for the complete catalogue.

The scanner produces a heuristic attack-surface inventory of route methods, observed guard signals, SQL tables and RLS signals, AI entrypoints, and MCP/agent files. Header checks cover recognized server configuration files; cookie checks cover common literal setter options. Both are advisory: external middleware, deployment settings and dynamic options require review. Signals do not prove guards or policies work, and code outside the scanned scope is not assessed. Run audit-skills separately for agent-integrity checks.

Generate an executive report or agent remediation prompt explicitly:

npx -y @vibefoundry/vibe-shield scan --report SECURITY-REPORT.md --patch-prompt PATCH-PROMPT.md
npx -y @vibefoundry/vibe-shield scan --format html --out security-report.html
npx -y @vibefoundry/vibe-shield audit-skills --report agent-report.html

Reports include severity, CWE, locations, snippets, OWASP 2025 web mappings for every rule and contextual LLM mappings when applicable, and illustrative remediation. Examples are not automatic project-specific patches; validate them against the application. The scanner itself is offline and read-only by default; --cache, --out, --report, --patch-prompt and init explicitly write files. Installing with npx can require network access. An A+ score applies only to the rules and files examined and is not a security certification.

npm 2.0.0 is already published and cannot be overwritten. It provides the scanner and MCP server but predates the universal --agents initializer in this repository. Use the GitHub v2 ref for that setup until a newer npm version is published. To exercise this checkout locally, run npm ci && npm run build, then node dist/bin/vibe-shield.js with the same arguments.


Related MCP server: supership-scan

The problem, in one file

This is the shape of code an agent writes when you ask for "a delete endpoint":

// app/api/users/route.ts
export async function DELETE(req: Request) {
  const { id, userId } = await req.json();
  await db.query(`DELETE FROM users WHERE id = ${id} AND owner = ${userId}`);
  return new Response('ok');
}

It works. It also has three critical vulnerabilities โ€” no authentication, SQL injection, and an IDOR that lets the caller choose whose data they delete. Nothing in a normal review loop catches all three, and the agent reported the task as complete.

npx -y @vibefoundry/vibe-shield scan catches all three in 17 milliseconds:

๐Ÿ›ก๏ธ  vibe-shield ยท security scan (illustrative output)
target  /home/you/app

๐Ÿ’€ GRADE F โ€” 0/100 ยท 3 critical

  CRITICAL 3    โ–ˆโ–ˆโ–ˆ

Findings

app/api/users/route.ts
  CRITICAL 2:1      VSB-AUTH-001  Next.js App Router mutation handler has no authentication check
           export async function DELETE(req: Request) {
  CRITICAL 4:22     VSB-DB-007    SQL statement built by concatenating request data
           await db.query(`DELETE FROM users WHERE id = ${id} AND owner = ${userId}`);
  CRITICAL 4:22     VSB-AUTH-004  Record ownership taken from the request instead of the session (IDOR)

  7 files  ยท  1 KiB  ยท  412 files/s  ยท  17 ms  ยท  79 rules

  โš   3 critical findings โ€” rotate any exposed credential before anything else.
  Fix it      npx -y @vibefoundry/vibe-shield scan --fix-prompt    # writes SECURITY_PATCH_PROMPT.md for your agent
  Explain     npx -y @vibefoundry/vibe-shield explain VSB-AUTH-001
  Gate CI     npx -y @vibefoundry/vibe-shield scan --fail-on critical --format github

Then hand the fix list to the agent that wrote the bug:

npx -y @vibefoundry/vibe-shield scan --fix-prompt   # โ†’ SECURITY_PATCH_PROMPT.md

That file contains, for every finding: the severity, the CWE id and link, the exact file:line, the vulnerable snippet, the ordered remediation steps, the target code shape, and a verification command. It is written for a machine to execute and a human to audit.


โšก Quick start

# 1. Scan (npx may download the package; the scanner itself is offline)
npx -y @vibefoundry/vibe-shield scan

# 2. Give your agent the fix list
npx -y @vibefoundry/vibe-shield scan --fix-prompt

# 3. Install the gate permanently โ€” skill + CI + ignore file
npx -y github:avivgerz-hue/vibe-shield#v2 init --agents all

Use the scoped name. vibe-shield is published as @vibefoundry/vibe-shield. The unscoped name vibe-shield on npm belongs to an unrelated project, so npx vibe-shield runs someone else's code. Always include the @vibefoundry/ scope. The package ships a prebuilt dist/, needs no TypeScript, and starts in milliseconds.

Supported Coding Agents (1-Command Setup)

Run this from the repository you want to protect (Node.js and Git required):

npx -y github:avivgerz-hue/vibe-shield#v2 init --agents all

To configure selected agents, substitute a comma-separated list such as --agents claude,cursor,zed:

Agent

Selector

Native integration

Claude Code

claude

.mcp.json, CLAUDE.md, .claude/skills/vibe-shield/SKILL.md, .claude-plugin/plugin.json

OpenCode

opencode

opencode.json MCP and AGENTS.md

OpenAI Codex CLI / universal agents

codex

AGENTS.md and .agents/skills/vibe-shield/SKILL.md

Cursor

cursor

.cursor/mcp.json and .cursor/rules/vibe-shield.mdc

Windsurf

windsurf

.windsurfrules

VS Code / GitHub Copilot

copilot

.vscode/mcp.json and .github/copilot-instructions.md

Cline / Roo Code

cline or roo

.clinerules

Zed

zed

.zed/settings.json context server

The existing --agent claude|cursor|generic|all remains supported. The shared .mcp.json, ignore file, and (unless --no-workflow is set) CI workflow are also installed. JSON configuration is merged by server name; malformed JSON or JSON with comments is left untouched and reported. Existing instructions are appended only once, and existing files are not overwritten without --force. Restart the relevant editor or reload its configuration after setup.

GitHub Marketplace Action

name: Security audit
on: [push, pull_request]
permissions:
  contents: read
  security-events: write
jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: avivgerz-hue/vibe-shield@v2
        with:
          target: .
          fail-on: high
          audit-skills: 'true'
          sarif-file: vibe-shield.sarif
      - uses: github/codeql-action/upload-sarif@v3
        if: ${{ always() && hashFiles('vibe-shield.sarif') != '' }}
        with:
          sarif_file: vibe-shield.sarif

The action runs the published @vibefoundry/vibe-shield@2.0.0 scanner, optionally audits skills, and fails if either enabled gate fails. SARIF upload is separate and requires GitHub code scanning support and appropriate permissions. The explicit target . includes tests and documentation, so review fixture findings in context.


๐Ÿง  Why AI code needs its own scanner

Traditional SAST rules are built around human mistakes: a forgotten escape, a missing prepare(). Agent-written code fails differently โ€” it is confidently complete and structurally plausible:

What a human does

What an agent does

forgets to validate one input

writes a perfect endpoint with no auth at all

uses eval in one legacy file

puts a tool execute that shells out behind an LLM

commits a .env by accident

puts SUPABASE_SERVICE_ROLE_KEY behind NEXT_PUBLIC_ because "it needed the env var"

writes CREATE TABLE

writes CREATE TABLE and forgets the ENABLE ROW LEVEL SECURITY, so the anon key reads everything

adds dangerouslySetInnerHTML to render a doc

renders model output with it, creating stored XSS with a step counter

vibe-shield encodes those specific shapes: 91 signatures across eight defensive categories, each one derived from a real agent-generated bug rather than a generic CWE checklist.


๐Ÿ“Š Vulnerability Coverage Matrix

79 code signatures + 12 agent-integrity signatures = 91. Every rule has an id, a CWE, an illustrative vulnerable shape, remediation guidance, and an OWASP association โ€” run npx -y @vibefoundry/vibe-shield rules or npx -y @vibefoundry/vibe-shield explain <ID>.

Client-side secret & data exposure โ€” VSB-CLIENT-*

ID

Detects

CWE

Sev

VSB-CLIENT-001

NEXT_PUBLIC_ / VITE_ / PUBLIC_ / REACT_APP_ + a server-only secret name (SERVICE_ROLE_KEY, OPENAI_API_KEY, STRIPE_SECRET_KEY, DATABASE_URLโ€ฆ)

CWE-200

critical

VSB-CLIENT-002

server-only process.env.*SECRET* read inside a "use client" module

CWE-200

high

VSB-CLIENT-003

createClient(url, SERVICE_ROLE_KEY) โ€” RLS bypass from a client-reachable file

CWE-250

critical

VSB-CLIENT-004

supabaseAdmin / adminClient / serviceRoleClient referenced from browser code

CWE-250

critical

VSB-CLIENT-005

dangerouslyAllowBrowser: true, provider SDK keyed in the browser

CWE-749

high

VSB-CLIENT-006

.env* assigns a live-looking credential to a public variable

CWE-540

critical

VSB-CLIENT-007

next.config.js env / publicRuntimeConfig / Vite define inlining a secret

CWE-798

critical

Unguarded mutation routes โ€” VSB-AUTH-*

ID

Detects

CWE

Sev

VSB-AUTH-001

App Router POST/PUT/PATCH/DELETE handler with no session check

CWE-306

critical

VSB-AUTH-002

Pages API mutation handler with no session check

CWE-306

critical

VSB-AUTH-003

Express / Fastify / Koa / Hono mutation route with no auth middleware

CWE-862

high

VSB-AUTH-004

IDOR โ€” ownership key from body/query/params (including the destructured local variable)

CWE-639

critical

VSB-AUTH-005

"use server" action mutating data with no auth

CWE-306

high

VSB-AUTH-006

identity from jwt.decode, x-user-id, atob(token.split('.')[1]), verify:false, algorithms:['none']

CWE-347

critical

VSB-AUTH-007

admin/destructive surface that authenticates but never checks a role

CWE-863

high

VSB-AUTH-008

const session = await auth() captured and never enforced

CWE-287

medium

VSB-AUTH-009

cookie-session mutation with no CSRF token protection

CWE-352

medium

Database exposure โ€” VSB-DB-*

ID

Detects

CWE

Sev

VSB-DB-001

CREATE TABLE with no ENABLE ROW LEVEL SECURITY anywhere in the project (cross-file index)

CWE-284

critical*/high

VSB-DB-002

permissive policy โ€” USING (true), WITH CHECK (true), USING (1=1)

CWE-732

critical

VSB-DB-003

anon/authenticated policy whose USING never references auth.uid()/auth.jwt()

CWE-639

high

VSB-DB-004

GRANT โ€ฆ TO anon/public (writes), incl. GRANT ALL

CWE-732

critical/high

VSB-DB-005

DISABLE ROW LEVEL SECURITY, DROP POLICY, BYPASSRLS

CWE-284

critical/high

VSB-DB-006

$queryRawUnsafe, $executeRawUnsafe, knex.raw, sequelize.query, .raw() with a dynamic string

CWE-89

critical

VSB-DB-007

hand-built SQL from request data โ€” ${}, +, Python f-strings, PHP interpolation

CWE-89

critical

VSB-DB-008

Supabase service-role key outside a server-only boundary

CWE-250

critical

VSB-DB-009

createBucket(โ€ฆ, { public: true })

CWE-732

medium

VSB-DB-010

request data used as a table, column or ORDER BY identifier

CWE-89

high

* critical when Supabase/PostgREST is detected โ€” the anon key in every browser makes the table publicly addressable.

AI / LLM & classic web โ€” VSB-AI-*

ID

Detects

CWE

Sev

VSB-AI-001

exec/execSync/spawn({shell:true})/Bun.spawn/os.system/subprocess(shell=True)/Runtime.exec/PHP backticks

CWE-78

critical

VSB-AI-002

LLM/MCP tool execute reaching a shell, eval or filesystem sink

CWE-94

critical

VSB-AI-003

model output into eval/new Function/vm.runInNewContext

CWE-94

critical

VSB-AI-004

untrusted/RAG content interpolated into a system prompt, no delimiters (OWASP LLM01)

CWE-74

high

VSB-AI-005

Stripe webhook without stripe.webhooks.constructEvent

CWE-345

critical

VSB-AI-006

webhook signing secret read from the request

CWE-345

high

VSB-AI-007

GitHub/Slack/Shopify/Svix webhook with no signature verification

CWE-345

high

VSB-AI-008

dangerouslySetInnerHTML, v-html, {@html}, innerHTML, document.write, jQuery .html()

CWE-79

high

VSB-AI-009

client eval/new Function/string setTimeout/javascript: URLs

CWE-94

high

VSB-AI-010

open redirect โ€” redirect(searchParams.get('next'))

CWE-601

medium

VSB-AI-011

SSRF โ€” fetch(req.body.url)

CWE-918

high

VSB-AI-012

path traversal โ€” path.join(dir, req.params.name)

CWE-22

high

VSB-AI-013

multer/formData() upload with no size or type limit

CWE-434

medium

VSB-AI-014

public LLM endpoint with no rate limit or quota

CWE-770

medium

VSB-AI-015

pickle.loads, yaml.load without SafeLoader, PHP unserialize

CWE-502

high

Hardcoded credentials โ€” VSB-SECRET-*

ID

Detects

CWE

Sev

VSB-SECRET-001

vendor signature in a server file (Stripe, OpenAI, Anthropic, AWS, GitHub, Supabase, Slack, Twilio, SendGrid, npm, PyPI, HuggingFace, Docker, Vercel, Mailgun, Square, Shopify, Datadog)

CWE-798

high

VSB-SECRET-002

generic high-entropy assignment to a credential-shaped name

CWE-798

medium/high

VSB-SECRET-003

PEM private key material

CWE-321

critical

VSB-SECRET-004

hardcoded JWT whose payload carries service_role / admin

CWE-250

critical

VSB-SECRET-005

the same vendor credential in a browser-reachable file

CWE-200

critical

VSB-SECRET-006

postgres:postgres@โ€ฆ, password = "admin", entropy < 2.5

CWE-1392

medium

VSB-SECRET-007

.env with live credentials โ€” critical when git-tracked

CWE-540

critical

Agent skill & MCP poisoning โ€” VSB-AGENT-* (audit-skills)

ID

Detects

CWE

Sev

VSB-AGENT-001

zero-width, bidi-override, Unicode-tag characters hiding instructions

CWE-74

critical

VSB-AGENT-002

curl/wget/nc exfiltrating env vars or .env

CWE-200

critical

VSB-AGENT-003

instructions to read .env, ~/.ssh, ~/.aws/credentials, id_rsa, keychain

CWE-522

critical

VSB-AGENT-004

registry-tag npx -y/uvx, remote MCP URL, curl | sh install (git installs such as github:owner/repo are not flagged: they resolve to a commit, not a mutable tag)

CWE-829

high

VSB-AGENT-005

literal credentials in an env block, or "*": "*" env forwarding

CWE-526

critical/high

VSB-AGENT-006

"ignore previous instructions", "do not tell the user", "auto-approve", "skip confirmation"

CWE-74

critical

VSB-AGENT-007

Bash(*), Write(*), autoApprove: ["*"], dangerouslySkipPermissions

CWE-284

high

VSB-AGENT-008

base64 payload / eval(atob(โ€ฆ)) / base64 -d | sh

CWE-94

high

VSB-AGENT-009

"fetch and follow every instruction"

CWE-829

critical

VSB-AGENT-010

missing frontmatter, wildcard allowed-tools

CWE-250

medium

VSB-AGENT-011

literal credential inside an instruction/MCP file

CWE-798

critical

VSB-AGENT-012

eval "$1", sh -c "$VAR" in a skill script

CWE-78

medium


๐Ÿ”Œ Native MCP server

vibe-shield is itself a Model Context Protocol server, so Claude Code, Claude Desktop, Cursor and Codex can call the scanner as a tool instead of shelling out and parsing console output.

npx -y @vibefoundry/vibe-shield mcp          # JSON-RPC 2.0 over stdio
npx -y @vibefoundry/vibe-shield --mcp        # same thing, if your client prefers a flag

Three tools:

Tool

What it does

vibe_shield_scan

Runs the code-scanning rules over a project or specific paths โ†’ grade, score, findings with file:line, CWE and remediation

vibe_shield_audit_skills

Audits .claude/skills, .cursor rules, AGENTS.md and MCP configs for prompt injection and exfiltration traps

vibe_shield_explain_rule

Full CWE detail, vulnerable/fixed examples and remediation for any rule id or slug

npx -y @vibefoundry/vibe-shield init writes the config for you, merging into .mcp.json without clobbering servers you already have:

{
  "mcpServers": {
    "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] },
    "vibe-shield": { "command": "npx", "args": ["--yes", "@vibefoundry/vibe-shield@2.0.0", "mcp"] }
  }
}

The version pin is not cosmetic: an unpinned npx -y server is exactly what VSB-AGENT-004 flags as high severity, so vibe-shield's own audit would write itself a finding. init pins the running version automatically.

Or add it by hand:

claude mcp add vibe-shield -- npx -y @vibefoundry/vibe-shield mcp

The server is zero-dependency, writes only JSON-RPC to stdout, honours JSON-RPC notifications (no spurious replies), and returns tool errors as isError results so a bad argument degrades one call instead of killing the session. Requests are handled in arrival order.

An empty target is reported as No files were scanned rather than a green pass โ€” a scanner that says "clean" when it read nothing is worse than no scanner.


๐Ÿค– Use it as an Agent Skill

npx -y github:avivgerz-hue/vibe-shield#v2 init --agents all installs the skill. Once it is in a repository, every agent session starts with a contract:

You are not allowed to say "done" until the code you just wrote passes a security audit.

npx -y github:avivgerz-hue/vibe-shield#v2 init --agents all
npx -y github:avivgerz-hue/vibe-shield#v2 init --agents claude
npx -y github:avivgerz-hue/vibe-shield#v2 init --agents cursor,zed --no-workflow

Why this works better than a prompt snippet: it names the three commands, gives the agent a reading guide for a finding (line:col, rule id, message, CWE), states five hard rules (never suppress, never weaken, always rotate, report honestly, re-verify), and defines "done" as an exit code rather than an opinion.

The skill itself is SKILL.md โ€” read it, it is short.

Anthropic Agent Skills quickstart

# marketplace-style install
npx -y @vibefoundry/vibe-shield init --agent claude
# โ†’ .claude/skills/vibe-shield/SKILL.md

# or globally, for every project
curl -sL https://raw.githubusercontent.com/avivgerz-hue/vibe-shield/main/SKILL.md \
  -o ~/.claude/skills/vibe-shield/SKILL.md

๐Ÿ” CI/CD: fail the PR before the bug ships

npx -y @vibefoundry/vibe-shield init installs a workflow that runs the scan, uploads SARIF to code scanning, audits the agent surface, and fails the job:

name: vibe-shield
on: [push, pull_request]

permissions:
  contents: read
  security-events: write

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Scan and upload SARIF
        run: npx -y @vibefoundry/vibe-shield scan --format sarif --out vibe-shield.sarif --fail-on high
        continue-on-error: true

      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: vibe-shield.sarif
          category: vibe-shield

      - name: Enforce the gate
        run: npx -y @vibefoundry/vibe-shield scan --fail-on high

Findings appear inline on the pull request diff (GitHub annotations) and in the Security โ†’ Code scanning tab (SARIF), so a reviewer sees the vulnerability on the line that introduced it.

Any other CI

npx -y @vibefoundry/vibe-shield scan --fail-on high                         # exit 1 on findings
npx -y @vibefoundry/vibe-shield scan --format compact                       # one line per finding
npx -y @vibefoundry/vibe-shield scan --format json > vibe-shield.json       # full report
npx -y @vibefoundry/vibe-shield scan --format summary                       # JSON, counts + grade only
npx -y @vibefoundry/vibe-shield scan --format github                        # workflow annotations

Exit codes: 0 clean ยท 1 findings at/above --fail-on ยท 2 usage error (a target path that does not exist, or a target that matches no scannable files). An empty scan prints NO FILES SCANNED โ€” this is not a pass and is never reported as a grade โ€” a gate pointed at an ignored path fails instead of succeeding forever.


๐ŸŽฏ The scorecard

Grades are deliberately unforgiving, because "B+" for a leaked production key is how security tools lose credibility:

Finding present

Maximum score

Best possible grade

any critical

29

F

any high

58

C

any medium

76

B

any low

88

A-

nothing

100

A+

Penalties per finding: critical โˆ’30, high โˆ’12, medium โˆ’5, low โˆ’2, info โˆ’0.5. One leaked live key fails the build on its own; a handful of informational notes never will.


๐Ÿช„ It scans itself

This repository runs its own gate on every commit and in CI:

$ npx -y @vibefoundry/vibe-shield scan
๐Ÿ›ก๏ธ  vibe-shield ยท security scan (illustrative output)
target  /you/vibe-shield

๐Ÿ† GRADE A+ โ€” 100/100

  21 files  ยท  172 KiB  ยท  236 files/s  ยท  89 ms  ยท  79 rules

  Nothing to fix. Keep the shield up. ๐Ÿ›ก๏ธ

$ npx -y @vibefoundry/vibe-shield audit-skills
๐Ÿ† GRADE A+ โ€” 100/100

  1 file  ยท  6 KiB  ยท  14 files/s  ยท  69 ms  ยท  12 rules

  Nothing to fix. Keep the shield up. ๐Ÿ›ก๏ธ

The detector catalogue is the one place that must contain the exact vulnerable shapes and vendor key formats the rules match on โ€” exactly like gitleaks and semgrep. Those files are listed explicitly in .vibe-shieldignore with a comment explaining why, instead of weakening a rule.


๐Ÿ”‡ Suppressing a finding (legitimately)

Inline, with a rule id and a reason โ€” the reason is required by review culture even though the parser does not enforce it:

// vibe-shield-disable-next-line VSB-AI-001 -- path comes from a closed enum
exec(`convert ${KNOWN_FORMATS[format]} out.png`);
// vibe-shield-disable-line VSB-AUTH-008
// vibe-shield-disable VSB-AI-014
// vibe-shield-enable
// vibe-shield-disable-file VSB-DB-004 -- generated edge schema

Suppressed findings are counted and reported in the scorecard, never silently dropped. Whole-path exclusions belong in .vibe-shieldignore (gitignore syntax) and should be reserved for generated code.


โš™๏ธ How it works

 discover โ”€โ”€โ–ถ project context โ”€โ”€โ–ถ rule gate โ”€โ”€โ–ถ detect โ”€โ”€โ–ถ suppress โ”€โ”€โ–ถ score โ”€โ”€โ–ถ report
   โ”‚              โ”‚                  โ”‚           โ”‚
   โ”‚              โ”‚                  โ”‚           โ””โ”€ 91 rules, each a pure (FileContext) => RuleHit[]
   โ”‚              โ”‚                  โ””โ”€ cheap content hints: most rules skip most files
   โ”‚              โ””โ”€ manifests, framework flags, cross-file RLS index, git index, middleware matchers
   โ””โ”€ one tree walk, gitignore/.vibe-shieldignore layering, binary + size + test/doc pruning

Design constraints, in priority order:

  1. Fast. One readdir walk, one read per file, one comment-masking pass, and a cheap gate before any rule body runs. A 400-file project scans in ~200 ms; a typical Next.js app in under 100 ms. No AST, no parser, no dependency.

  2. Honest. Every finding carries the exact snippet the developer wrote. Configuration checks may infer risk from file shape, and every suppression is counted, not hidden.

  3. Composable. scanProject() for the CLI, runRulesOnFile() for the auditor, scoreFindings() for anything that produces findings. The whole API is exported from vibe-shield.

Zero runtime dependencies. No network calls, no telemetry, no language server, no native binaries. The scanner works offline once installed; a first-time npx install needs registry access.


๐Ÿ“– CLI reference

vibe-shield scan [paths...]         Scan the project (default: `.`)
vibe-shield audit-skills [paths...] Audit agent skills, rules, AGENTS.md and MCP config
vibe-shield init                    Install the Agent Skill, AGENTS.md, .mcp.json and CI gate
vibe-shield mcp                     Serve the MCP tools over stdio
vibe-shield rules                   List every detection rule
vibe-shield explain <RULE_ID>       Full documentation for one rule
vibe-shield version | help

Flag

Default

Meaning

--format <fmt>

console

console compact summary json sarif github markdown html

--fail-on <sev>

critical

Exit 1 at/above this severity

--severity <sev>

โ€”

Only report at/above this severity

--fix-prompt

off

Write SECURITY_PATCH_PROMPT.md

--out <file>

โ€”

Write the report to a file

--rules <ids>

all

Comma-separated ids/slugs, supports VSB-DB-*

--ignore <glob>

โ€”

Extra ignore pattern (repeatable)

--include-tests

off

Include test/fixture files

--include-docs

off

Include Markdown and docs/

--cache

off

Reuse .vibe-shield-cache.json

--max-findings <n>

50

Console list cap (0 = all)

--quiet

off

One-line verdict (100/100 A+ โ€” 0 critical, โ€ฆ)

--no-color

auto

Disable ANSI (also honours NO_COLOR)

--json

off

Shorthand for --format json

--no-gitignore

off

Ignore .gitignore while discovering files

--no-shield-ignore

off

Ignore .vibe-shieldignore (e.g. to scan excluded fixtures)

init takes --target <dir>, --agent claude / cursor / generic / all, --no-workflow, --force and --yes.


๐Ÿงฉ Programmatic API

import { scanProject, formatSarif, buildPatchPrompt, auditSkills } from 'vibe-shield';

const result = await scanProject({ rootDir: process.cwd(), cache: true });

console.log(result.score.score, result.score.grade);  // 0 'F'
console.log(result.findings[0].ruleId);               // 'VSB-AUTH-001'
console.log(result.findings[0].cwe.id);               // 'CWE-306'

process.stdout.write(formatSarif(result));            // SARIF 2.1.0
process.stdout.write(buildPatchPrompt(result));       // agent-ready fix list

const agentReport = await auditSkills(process.cwd()); // VSB-AGENT-* surface

โ“ FAQ

Does it replace a real SAST tool? No. It replaces the absence of one. vibe-shield is a fast, zero-dependency gate you can put in front of every agent-written commit today. Pair it with a deeper scanner (CodeQL, Semgrep) if you have one; the rules overlap far less than you would expect, because these are agent-specific shapes.

Will it flag my secure code? The secure fixture (tests/fixtures/secure/) is a real Next.js + Supabase + Stripe app with auth, RLS, sanitisation, rate limiting and webhook verification โ€” it scores 100/100 and the suite asserts zero findings on it. Each rule has guard clauses for the legitimate patterns: import "server-only" suppresses the service-role rules, Prisma tagged templates suppress the SQLi rule, DOMPurify suppresses the XSS rule, auth.uid() policies suppress the RLS rules.

Does it send my code anywhere? No. There is no network code in the runtime at all โ€” the package has zero dependencies and makes no outbound requests.

Why not an AST? Because a 1.5 MB minified bundle, a Vue SFC, a PHP legacy file and a SQL migration all need to be scanned with the same tool, and a parser handles exactly one of those. The rules use structural brace matching plus a comment-masker that preserves offsets, which is enough for the shapes that matter and roughly two orders of magnitude faster.

Why "vibe"? Because the code was written by vibe and reviewed by nobody. This is the reviewer.


๐Ÿ›  Development

git clone https://github.com/avivgerz-hue/vibe-shield
cd vibe-shield
npm ci
npm run typecheck   # tsc --noEmit (strict, noUnusedLocals)
npm test            # 224 Vitest tests
npm run build       # tsc + postbuild (shebang, chmod, CJS marker)
npm run verify      # typecheck + test + build + self-scan + self-audit

See CONTRIBUTING.md for the rule-authoring guide, and SECURITY.md for the threat model and disclosure policy.


๐Ÿ“‹ Requirements

  • Node.js โ‰ฅ 18.17 (uses node: builtins only โ€” no polyfills, no native modules)

  • Any OS: Linux, macOS, Windows

  • No config file required; package.json is optional


๐Ÿ“„ License

MIT ยฉ VibeFoundry โ€” use it, fork it, ship it.


Part of the VibeFoundry Agent Suite

Three tools for the same problem: agents move fast, and something has to keep the output honest.

Tool

What it does

๐ŸŽจ

unslop

Studio-grade UI design systems & Anti-Slop engine โ€” stops agents from generating generic, interchangeable interfaces

๐Ÿ›ก๏ธ

vibe-shield

Security scanner & MCP guard โ€” stops agents from shipping leaked keys, unguarded routes and disabled RLS

๐Ÿ‘ป

ghost-qa

Autonomous headless-browser QA & self-healing verification loop โ€” stops agents from claiming a UI works when it does not

npx -y @vibefoundry/vibe-shield init   # security gate

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelogโ€ฆ

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      B
      maintenance
      Security MCP server with 300+ rules for AI-generated code. Scans Next.js, Supabase, Clerk, Stripe, Prisma, Hono, GraphQL and 20+ modules. Zero config, runs locally.
      39
      1,225 npm
      6
      Apache 2.0
    • A
      license
      Not graded
      quality
      F
      maintenance
      Predeploy security scanner for AI-generated code. 80+ vulnerability patterns across secrets, auth, injection, config, Supabase, and logging. Runs locally, code never leaves your machine. Optional x402 witnessed attestation.
      94 npm
      Apache 2.0
    • A
      license
      C
      quality
      D
      maintenance
      Security scanner and MCP server that catches dangerous patterns in MCP servers and AI agent projects, such as leaked secrets, shell execution, and prompt-injection text. Runs as both a CLI and MCP server with CI-friendly severity gates.
      2
      1
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables MCP-compatible AI agents to scan code for leaked secrets, copyleft licenses, unprotected routes, missing privacy policies, and risky card handling before committing or shipping.
      73 npm
      MIT