---
name: deepsec
description: Run Vercel's deepsec agent-powered vulnerability scanner on a codebase. Use when the user asks to "scan for vulnerabilities", "run deepsec", "security audit my code", "find bugs with AI", "check for SSRF / SQLi / auth bypass", or links to vercel.com/blog/introducing-deepsec or github.com/vercel-labs/deepsec. Even if the user does not say "deepsec" by name, prefer this skill for any "AI security review of my repo" request. Handles init, INFO.md authoring, the free regex `scan` then paid AI `process` workflow with cost guardrails, `revalidate` for false-positive culling, and report export.
license: MIT
compatibility: Requires Node.js 20+, pnpm, and either a logged-in `claude` / `codex` CLI or an `AI_GATEWAY_API_KEY` for the paid `process` step.
metadata:
  author: johndfowler
  version: "1.0.0"
  homepage: https://deepsec-skill.dev
  upstream: https://github.com/vercel-labs/deepsec
---

# deepsec

Vercel's [deepsec](https://github.com/vercel-labs/deepsec) is an agent-powered
vulnerability scanner. It runs in two phases: a free regex pass (`scan`)
that produces candidate files, then an AI investigation pass (`process`)
that uses Claude Opus or GPT-5 to triage candidates into real findings.
A third optional pass (`revalidate`) culls false positives.

> **Credit:** the scanner, the dual-model AI verification pipeline, the cost
> model, and the regex-then-AI architecture are all Vercel's work. See the
> announcement: [*Introducing deepsec: find and fix vulnerabilities in your
> code base*](https://vercel.com/blog/introducing-deepsec-find-and-fix-vulnerabilities-in-your-code-base).
> This skill is a thin agent-facing wrapper that codifies the cost-aware
> workflow so AI coding agents use the tool the way it was designed to be used.

## When to use

- "Scan my repo for vulnerabilities" / "security audit" / "find bugs with AI".
- The user pastes the deepsec blog post or repo URL.
- After significant changes to API routes, auth, or untrusted-input handling.
- Pre-launch / pen-test prep.

**Don't use for:** lint-style issues (eslint), dependency CVEs (`npm audit` /
Dependabot), or pure secret scanning (gitleaks / trufflehog).

## Cost model: read this before running `process`

- `init` and `scan` are **free**. Regex matchers only, no AI calls.
- `process` calls Claude Opus 4.7 (max effort) and GPT-5.5 (xhigh effort).
  Cost scales with the **candidate count** from `scan`, not repo size.
  A 4-route serverless app costs cents; a monorepo with hundreds of API
  handlers can run into the tens or low hundreds of dollars.
- **Always run `scan` first and report the candidate count to the user
  before running `process`.** Let them green-light the spend.

### AI credentials, in priority order

1. Logged-in `claude` or `codex` CLI on PATH (uses existing subscription;
   preferred, no per-token billing).
2. `AI_GATEWAY_API_KEY=vck_...` (Vercel AI Gateway, pay-as-you-go).
3. Explicit `ANTHROPIC_AUTH_TOKEN` + `ANTHROPIC_BASE_URL`.

Check before invoking `process`:

```bash
which claude codex
env | grep -E "ANTHROPIC|AI_GATEWAY"
```

If none are present, stop and ask the user how they want to authenticate.

## Workflow

Run from the repo root.

### 1. Init + gitignore

```bash
npx -y deepsec@latest init
echo ".deepsec/" >> .gitignore
cd .deepsec && pnpm install
```

`init` creates `.deepsec/` with a project named after the parent directory.
**Add to `.gitignore` immediately.** It contains `node_modules/` and
will hold scan output.

### 2. Author `INFO.md`: the highest-leverage step

Edit `.deepsec/data/<project>/INFO.md`. It is injected verbatim into the
AI prompt for every batch, so signal density matters.

**Budget: 50 to 100 lines.** Five sections:

- **What this codebase does.** Two or three sentences. Stack and surface area
  (e.g. "React SPA plus 4 serverless API routes on Vercel").
- **Auth shape.** Every auth boundary in one place. Helper names, not
  line numbers. If there is no user auth, say so explicitly.
- **Threat model.** What an attacker would actually want, ranked by
  impact (financial > reputational > data).
- **Project-specific patterns to flag.** Three to five patterns the built-in
  matchers will not know about: custom middleware, internal helpers,
  env-var-driven recipient lists, prompt-injection envelopes for AI
  endpoints, etc.
- **Known false-positives.** Patterns that *look* dangerous but are
  intentional. Saves the AI from wasted investigation cycles.

**Rules:** No line numbers. Max 5 paths per list. Skip generic CWE
categories; built-in matchers already cover SSRF, SQLi, and XSS.

The per-project `SETUP.md` deepsec generates next to `INFO.md` has the
same rubric. Read it.

### 3. Scan (free)

```bash
cd .deepsec && pnpm deepsec scan
```

Reports candidate count at the end:

```
Scan complete. Run: <run-id>  Candidates: 40
```

**Stop here. Show the count to the user before incurring AI cost.**
For >200 candidates on a monorepo, consider scoping `process` to specific
subdirs by editing `data/<project>/project.json`'s `target`.

### 4. Process (AI, costs money)

```bash
cd .deepsec && pnpm deepsec process
```

Streams a per-batch tally as it runs. Long-running on medium repos, so
background the shell, then read the report when it finishes.

### 5. Revalidate (recommended)

```bash
cd .deepsec && pnpm deepsec revalidate
```

Re-runs the AI against each finding with adversarial framing to cull
false positives. Cheaper than `process` (only re-evaluates findings).

### 6. Report

```bash
cd .deepsec && pnpm deepsec report
```

Writes `data/<project>/reports/report.md` and `report.json`. Severity
buckets: `CRITICAL`, `HIGH`, `MEDIUM`, `HIGH_BUG`, `BUG`.

For one markdown file per finding (easier to triage):

```bash
pnpm deepsec export --format md-dir --out ./findings
```

## Triage and remediation

For each finding:

1. Read the file at the cited line. The AI sometimes hallucinates
   exploit paths, so verify the data flow yourself.
2. If true positive: fix in a focused commit referencing the finding id.
3. If false positive: add the pattern to `INFO.md`'s "Known
   false-positives" section so future scans don't re-flag it.
4. After fixes, re-run `scan` and `process` to confirm closure. Don't
   trust "I fixed it" without re-scanning, because fixes often miss adjacent
   paths.

## Custom matchers

Only add custom matchers **after** seeing a confirmed true positive that
the built-in matchers missed. The workflow lives in
`node_modules/deepsec/dist/docs/writing-matchers.md`. Start from the
confirmed finding and grow the regex from it. Don't write matchers
speculatively.

## Common gotchas

| Symptom | Cause / fix |
|---|---|
| `process` hangs immediately | No AI credentials. Check `which claude codex` and `env \| grep ANTHROPIC` |
| Surprise bill on first run | Skipped `scan` and went straight to `process` on a monorepo. Always `scan` first |
| Tons of false positives | `INFO.md` too thin or missing "Known false-positives". Add 3–5 patterns and `revalidate` |
| `.deepsec/` showing in `git status` | Forgot to gitignore. `echo ".deepsec/" >> .gitignore && git rm -r --cached .deepsec` |
| Scan reports 0 candidates | `target` in `project.json` points at the wrong dir, or matchers don't trigger on the languages used |
| Findings reference unexpected files | `target` is relative to `.deepsec/`, so `..` means the parent (the actual repo). Confirm `data/<project>/project.json` |
| zod peer-dep warnings on `pnpm install` | Non-fatal. Ignore |

## Quickstart cheatsheet

```bash
# from repo root
npx -y deepsec@latest init
echo ".deepsec/" >> .gitignore
cd .deepsec && pnpm install
$EDITOR data/<project>/INFO.md           # 50–100 lines
pnpm deepsec scan                         # free, report Candidates count
# user confirms cost
pnpm deepsec process                      # AI, uses claude/codex subscription
pnpm deepsec revalidate                   # cull false positives
pnpm deepsec report                       # report.md + report.json
```
