1---2name: oma-deepsec3description: Set up and run Deepsec vulnerability scans, triage, and CI gates. Use for Deepsec work or an explicitly requested agent-powered vulnerability scan.4---56# Deepsec: Agent-Powered Vulnerability Scanner Driver78## Scheduling910### Goal11Operate Vercel's `deepsec` security scanner inside a target repository safely and cost-consciously: bootstrap the `.deepsec/` workspace, write a tight `INFO.md`, run the right scan/process/triage/revalidate/export sequence, gate PRs in CI via `process --diff`, and grow project-specific matchers, surfacing real, revalidated findings without runaway spend.1213### Intent signature14- User mentions `deepsec`, "deep security scan", `bunx deepsec`, `pnpm deepsec`, `npx deepsec`.15- User asks an agent to scan a repository for vulnerabilities, security issues, or CVEs and the project has (or should have) a `.deepsec/` directory.16- User asks how to add a deepsec PR / CI security gate, or about `process --diff`, `--diff-staged`, `--diff-working`, `--files-from`, `--comment-out`.17- User mentions deepsec artefacts: `INFO.md`, `SETUP.md`, `data/<id>/files/`, `FileRecord`, `RunMeta`, `revalidation`, `triage`, custom matchers, `MatcherPlugin`, `noiseTier`, `priorityPaths`.18- User asks about deepsec configuration: `deepsec.config.ts`, `defaultAgent`, `AI_GATEWAY_API_KEY`, `VERCEL_OIDC_TOKEN`, AI Gateway, Vercel Sandbox, `--agent codex`, `--agent claude`.19- User asks how to lower deepsec cost, cut false-positive rate, or interpret severity / triage / revalidation verdicts.2021### When to use22- First-time deepsec install in a repo (`init`, `INFO.md` write, first calibration scan).23- Running a full or scoped scan and processing findings.24- Setting up a per-PR CI gate with `process --diff` and `--comment-out`.25- Writing a project-specific matcher to cover entry points the default set misses.26- Triaging a backlog of findings (severity bucketing, FP cuts via `revalidate`, exporting to issue tracker).27- Diagnosing deepsec failures: missing credentials, AI Gateway quota stops, refusals, sandbox auth.2829### When NOT to use30- Generic OWASP / lint-style review without deepsec → use `oma-qa`.31- Generic CVE / dependency advisories → use `oma-qa` or `oma-search`.32- Architecting a brand-new SAST pipeline that is not deepsec → use `oma-architecture`.33- Writing or auditing application code itself → route to `oma-backend` / `oma-frontend` / `oma-mobile`.34- Cloud / IAM / Terraform hardening → use `oma-tf-infra` (deepsec only scans the IaC; remediation lives there).35- Pure reasoning about a finding's fix in product code → use `oma-debug` once deepsec has produced the finding.3637### Expected inputs38- `target_repo_root`: absolute path of the codebase to scan (parent of `.deepsec/`).39- `intent`: one of `setup` | `scan` | `pr-review` | `matchers` | `triage` | `config` | `troubleshoot`.40- `credential_mode`: `ai-gateway-key` | `vercel-oidc` | `direct-anthropic` | `direct-openai` | `subscription`.41- `agent_choice`: `codex` (upstream default; model `gpt-5.5`) or `claude` (model `claude-opus-4-8`). Asked once before the first paid call if not already provided.42- `severity_floor`: lowest severity worth surfacing (typically `HIGH`).43- Optional: existing `.deepsec/data/<id>/`, `deepsec.config.ts`, custom matchers, CI provider.4445### Expected outputs46- A working `.deepsec/` workspace registered against the target repo.47- A populated `data/<id>/INFO.md` (50-100 lines, project-specific, no line numbers).48- One or more completed `scan` → `process` (→ `triage`/`revalidate`) runs with reproducible cost notes.49- For PR mode: a CI workflow file using `process --diff <base>` with two-job split (no PR-write in PR-code job).50- For matchers: new `.deepsec/matchers/<slug>.ts` files wired through the inline plugin in `deepsec.config.ts`.51- A findings export (`md-dir` and/or `json`) plus a short summary of top severities and FP-rate notes.52- Explicit, dollar-and-time-bounded plan before any pass that may cost more than ~$25.5354### Dependencies55- Node.js **22+**, plus a package manager: `bun` / `bunx` (preferred in this monorepo), `pnpm`, `npm`, or `yarn`.56- A working AI credential: `AI_GATEWAY_API_KEY=vck_…`, or `VERCEL_OIDC_TOKEN`, or direct `ANTHROPIC_AUTH_TOKEN` + `ANTHROPIC_BASE_URL`, or a logged-in `claude` / `codex` CLI subscription.57- Git (history is consulted by `revalidate` and `--diff` modes).58- Optional: Vercel Sandbox auth for `deepsec sandbox …` distributed runs.59- Reference resources under `resources/` (loaded only when the scenario requires them).6061### Control-flow features62- Branches by `intent` (setup vs scan vs pr-review vs matchers vs triage vs config vs troubleshoot).63- Branches by repo size (calibrate with `--limit 50` before any large pass).64- Branches by credential source (gateway key, OIDC, direct, subscription).65- Stops on quota / credit exhaustion and resumes the same command after top-up.66- Refuses to launch an unbounded `process` when no calibration has been done and the repo is large.67- Reads codebase, writes `.deepsec/` files and CI configs, runs long-lived AI processes.6869## Structural Flow7071### Entry721. Confirm whether `.deepsec/` already exists; if yes, treat the run as **incremental**, never re-init.732. Resolve `intent` from the user prompt; if ambiguous (e.g. "scan this repo"), default to `setup` then `scan` (calibration mode).743. Estimate scale: count source files (rough `rg --files | wc -l` excluding `node_modules`, `.git`, `dist`) to forecast cost before any AI pass.754. Check for an AI credential in `.env.local` or shell env; if none, route to credential setup before any `process` / `revalidate` / `triage` call.765. **Confirm agent choice with the user before the first paid call.** If `agent_choice` is not already in the prompt and `deepsec.config.ts` does not pin a `defaultAgent`, ask whether to run `codex` (`gpt-5.5`, the upstream default; runs in a strict sandbox, cheaper, grep-heavy) or `claude` (`claude-opus-4-8`; strongest reasoning, most expensive). The two backends can be mixed via `--reinvestigate` and findings dedupe across agents. Skip the question if the user has already named an agent or has explicitly delegated the decision ("just pick reasonable defaults").7778### Transitions79- If `.deepsec/` is missing and intent involves scanning → run `bunx deepsec init` (or `npx deepsec init`) and follow the printed prompt to populate `INFO.md` before any AI pass.80- If `INFO.md` is empty or template-shaped → write it (50-100 lines, project-specific, 3-5 examples per section, no line numbers, no generic CWE enumeration).81- If repo is > 500 files and no calibration has run → run a calibration pass first (deepsec docs recommend `--limit 50 --concurrency 5`) and report cost extrapolation before the full pass.82- If a `process` / `revalidate` run halts on quota → leave file locks intact, surface the exact remediation URL, **re-run the same command after top-up**.83- If the agent reports a refusal (`refused: true`) → never silently drop; document the affected files and either retry with the other backend or add the path to `config.json:ignorePaths` only if reproducible.84- If the user wants a CI gate → emit the two-job pattern (PR-code job has no `pull-requests: write`, comment job has no PR code).85- If the user wants more matcher coverage → run the matcher-authoring workflow against `data/<id>/files/` and the parent repo's entry points.8687### Failure and recovery88| Failure | Recovery |89|---------|----------|90| `Missing AI credentials for --agent claude` / `codex` | Pick a credential mode (gateway key / OIDC / direct / subscription) per `resources/config.md` and write `.env.local`. |91| `401 Unauthorized` from gateway | OIDC: re-run `vercel env pull` (12 h expiry). API key: regenerate. Confirm `.env.local` is in the cwd deepsec runs from. |92| `Stopped: AI Gateway credits exhausted` | Top up via the printed URL; re-run the same command, files already done are skipped. |93| `Stopped: Claude Pro/Max subscription exhausted` | Switch to AI Gateway; subscriptions don't carry full scans. |94| Persistent refusal on a single file (>5% of batches) | Add the path to `data/<id>/config.json:ignorePaths`, or run that file alone with `--batch-size 1`. |95| FP rate too high on `HIGH+` | Run `revalidate --min-severity HIGH`; tighten `INFO.md`'s threat model and FP notes; bias matchers to `precise`. |96| `noisy` matcher wedges scanner on a 100k-file repo | Tighten `filePatterns` to language- or directory-anchored globs. |97| Sandbox auth fails | OIDC: re-run `vercel env pull`. Access-token mode: verify `VERCEL_TOKEN` + `VERCEL_TEAM_ID` + `VERCEL_PROJECT_ID`. |98| User asks for full scan with no budget context | Halt; report file count and forecast cost band; require explicit go-ahead before the full pass. |99100### Exit101- **Success**: planned passes ran, findings exist with verdicts (or no findings produced), files written are listed, residual cost / followups are explicit.102- **Partial success**: some passes blocked on credentials/quota/refusal; the blocker, the safe-resume command, and the recommended next step are reported.103- **Failure**: nothing destructive happened, the user has the exact next command to unblock the work.104105## Logical Operations106107### Tools and instruments108- **Package manager**: `bun` / `bunx` (preferred), `pnpm`, `npm`, `yarn` are interchangeable.109- **CLI commands**: `deepsec init`, `init-project`, `scan`, `process`, `process --diff`, `triage`, `revalidate`, `enrich`, `report`, `export`, `metrics`, `status`, `sandbox <cmd>`.110- **Diff sources for PR mode**: `--diff <ref|range>`, `--diff-staged`, `--diff-working`, `--files <csv>`, `--files-from <path>` (or `-` for stdin).111- **Inspection**: `jq` over `data/<id>/files/**/*.json` for ad-hoc severity / TP queries.112- **Credentials**: `AI_GATEWAY_API_KEY`, `VERCEL_OIDC_TOKEN`, `ANTHROPIC_AUTH_TOKEN` / `ANTHROPIC_BASE_URL`, `OPENAI_API_KEY` / `OPENAI_BASE_URL`, `claude login`, `codex login`.113- **Resource files** under `resources/` for setup, scanning, PR review, matchers, triage, config, load on demand.114115### Canonical workflow path1161. **Bootstrap** (one time per repo):117 ```bash118 cd <target-repo>119 bunx deepsec init120 cd .deepsec121 bun install122 # Edit .env.local: set AI_GATEWAY_API_KEY=vck_… (or VERCEL_OIDC_TOKEN via `vercel env pull`)123 ```124 Then prompt the coding agent (this skill) to read125 `.deepsec/node_modules/deepsec/SKILL.md` and `.deepsec/data/<id>/SETUP.md`,126 skim `README` / `AGENTS.md` / `CLAUDE.md` and a handful of representative127 files, and replace each section of `data/<id>/INFO.md` (50-100 lines,128 3-5 examples per section, no line numbers, no generic CWE rehash).1292. **Calibrate before any full pass.** The deepsec docs (`getting-started.md`, `vercel-setup.md`, `faq.md`) recommend `--limit 50 --concurrency 5` as the calibration starting point.130 ```bash131 bunx deepsec scan132 bunx deepsec status133 bunx deepsec process --limit 50 --concurrency 5134 ```135 Read the per-batch cost. Extrapolate to full repo. Get the user's explicit go-ahead before the full `process`. If the user names different `--limit` / `--concurrency` values, use theirs.1363. **Full investigation, triage, revalidate, export**:137 ```bash138 bunx deepsec process --concurrency 5139 bunx deepsec triage --severity HIGH140 bunx deepsec revalidate --min-severity HIGH141 bunx deepsec export --format md-dir --out ./findings142 bunx deepsec metrics143 ```1444. **PR mode** (CI gate, scoped to changed files, exit code = 0/1):145 ```bash146 bunx deepsec process \147 --diff origin/${BASE_REF} \148 --comment-out comment.md149 ```150 Wire the two-job CI pattern from `resources/pr-review.md`. Never grant `pull-requests: write` to the job that runs PR-controlled code.1515. **Custom matchers** (close entry-point gaps surfaced in step 3):152 - Read the contract in `.deepsec/node_modules/deepsec/dist/config.d.ts` and the `samples/webapp/matchers/*` examples.153 - Write `.deepsec/matchers/<slug>.ts`, wire it through the inline plugin in `.deepsec/deepsec.config.ts`.154 - Verify hit rate: `bunx deepsec scan --matchers <slug>` should land in 1-20 hits / 1k files (`precise`), 5-100 (`normal`), or roughly the framework entry-point count (`noisy`).1556. **Resume** after any quota stop, network blip, or Ctrl-C: re-run the same command. State is on disk under `.deepsec/data/<id>/`.156157### Resource scope158| Scope | Resource target |159|-------|-----------------|160| `CODEBASE` | Target repo source files, framework configs, route directories, `README` / `AGENTS.md` / `CLAUDE.md`. |161| `LOCAL_FS` | `.deepsec/deepsec.config.ts`, `.deepsec/.env.local`, `.deepsec/matchers/`, `.deepsec/data/<id>/{project.json,INFO.md,config.json,files/,runs/,reports/}`, generated `findings/`, `comment.md`, CI workflow files. |162| `PROCESS` | `bunx deepsec scan|process|triage|revalidate|export|metrics|status|sandbox`, `bun install`, optional `vercel link` / `vercel env pull`. |163| `NETWORK` | Anthropic / OpenAI via Vercel AI Gateway (default) or direct provider endpoints; optional Vercel Sandbox microVM control plane. |164| `CREDENTIALS` | `AI_GATEWAY_API_KEY`, `VERCEL_OIDC_TOKEN`, `ANTHROPIC_AUTH_TOKEN`, `OPENAI_API_KEY`, `VERCEL_TOKEN` / `VERCEL_TEAM_ID` / `VERCEL_PROJECT_ID`, `claude` / `codex` subscription tokens. Consume read-only; never echo secrets back to the user or commit them. |165| `MEMORY` | User-stated budget cap, severity floor, and stop conditions for the current session. |166167### Preconditions168- Node.js 22+ is available.169- Repo is a git checkout (deepsec uses git history for `revalidate` and `--diff`).170- For any AI command: at least one credential mode is configured *before* the call, or the call is held until one is.171- For `sandbox` mode: Vercel auth is wired; otherwise stay local.172- For unbounded `process` runs on > 500-file repos: a `--limit` calibration pass has produced a cost number the user has acknowledged.173174### Effects and side effects175- Creates `.deepsec/` (config, lockfile, scaffolding) and `.deepsec/data/<id>/` (gitignored) inside the target repo.176<!-- oma-docs:ignore-start -->177- Writes `.env.local` (never commit) and may run `vercel link` / `vercel env pull` (writes `.vercel/project.json` + token).178<!-- oma-docs:ignore-end -->179- Spawns long-running AI processes that **cost real money**. Single full scans range from $25 to over $1,200 per the official cost guide and can climb to tens of thousands on very large repos.180- Reads source code; sends snippets to the configured LLM (gateway = zero retention; direct provider = subject to that provider's policy). Never exfiltrates secrets; the gateway key stays outside the worker sandbox in `sandbox` mode.181<!-- oma-docs:ignore-start -->182- May write `.github/workflows/deepsec.yml` (or analogue) when the user asks for a CI gate.183<!-- oma-docs:ignore-end -->184- Edits `deepsec.config.ts` and adds `.deepsec/matchers/*.ts` when authoring matchers.185- Does not commit, push, or open PRs unless the user explicitly authorizes a separate commit step (route via `oma-scm`).186187### Guardrails1881. **Never launch an unbounded `process` on a repo whose size you have not measured.** Always run a calibration pass first when file count is unknown or > 500 (deepsec docs recommend `--limit 50 --concurrency 5`; defer to a user-named value if given).1892. **State cost and stopping condition before any AI pass.** Use the published bands (100 files ≈ $25-60, 500 ≈ $130-300, 2,000 ≈ $500-1,200; ×2-3 swing).1903. **Resume, do not reset.** After any network / quota / Ctrl-C interruption, re-run the same command. Never delete `data/<id>/` to "start clean" without explicit user instruction.1914. **`INFO.md` stays short and project-specific.** 50-100 lines, 3-5 examples per section. Name primitives but no line numbers. Skip generic CWE categories; built-in matchers cover those.1925. **For PR/CI gates, keep PR-controlled code in a no-write job.** Never grant `pull-requests: write` to a job that executes PR-controlled `pnpm install` / config-loading. Use the two-job pattern in `resources/pr-review.md`.1936. **Pin actions to full SHAs** in production CI; major-version tags are for examples only.1947. **Never silently drop refusals.** If the agent reports `refused: true`, log it, retry with the other backend, or add the file to `ignorePaths` only when reproducible.1958. **Bias matchers toward `precise` when the bug shape is exact.** Reserve `noisy` for entry-point coverage and tight globs.1969. **Never echo or commit credentials** (`vck_…`, `sk-ant-…`, `sk-…`, OIDC tokens). Treat `.env.local` as secret. Treat `data/` as gitignored by default.19710. **Treat deepsec like an agent with shell access.** Recommend `sandbox` for prompt-injection-prone repos (vendored code, untrusted deps).19811. **Findings need verdicts.** For any HIGH+ surfaced to the user, prefer `revalidate`-tagged verdicts (`true-positive` / `false-positive` / `fixed` / `uncertain`) over raw `process` output.19912. **Do not invent CLI flags, and trust the CLI over these notes.** Anything beyond `resources/scanning.md`'s flag list must be checked against `--help` first. Likewise, when the CLI's printed model names, defaults, or per-batch costs disagree with the values written in this skill, the CLI is right — upstream moves faster than these resources.20013. **Ask agent choice before the first paid call.** If the user has not named an agent (`claude` vs `codex`) and `deepsec.config.ts` does not pin `defaultAgent`, ask once with the trade-off clearly stated. Do not also bargain over budget or severity; those are handled via the upstream calibration recommendation (`--limit 50 --concurrency 5` per deepsec docs) and the user-stated `severity_floor`.201202## References203- Workspace install + `INFO.md` bootstrap: `resources/setup.md`204- Full scan/process/triage/revalidate/export workflow + cost guide: `resources/scanning.md`205- PR / CI gate via `process --diff` (two-job pattern, exit-code semantics): `resources/pr-review.md`206- Authoring custom matchers (slugs, noise tiers, file globs, plugin wiring): `resources/matchers.md`207- Reading findings, severities, triage / revalidation verdicts, FP cuts: `resources/triage.md`208- `deepsec.config.ts` reference, env vars, plugin order, AI Gateway / Vercel Sandbox auth: `resources/config.md`209- Upstream docs (load only when a resource file points at one):210 - Repo + README: https://github.com/vercel-labs/deepsec211 - Per-topic docs at https://github.com/vercel-labs/deepsec/tree/main/docs (`getting-started`, `reviewing-changes`, `writing-matchers`, `configuration`, `models`, `plugins`, `architecture`, `data-layout`, `vercel-setup`, `supported-tech`, `faq`)212- Shared context loading: `../_shared/core/context-loading.md`213- Shared quality principles: `../_shared/core/quality-principles.md`