security-scanner
Use when reviewing code changes for security issues — during REVIEW phase or on explicit security, vulnerability, SAST, or secret-scan requests — running available Semgrep/Opengrep, Trivy, and Gitleaks scanners with a self-healing fix loop
Best use case
security-scanner is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use when reviewing code changes for security issues — during REVIEW phase or on explicit security, vulnerability, SAST, or secret-scan requests — running available Semgrep/Opengrep, Trivy, and Gitleaks scanners with a self-healing fix loop
Teams using security-scanner should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/security-scanner/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How security-scanner Compares
| Feature / Agent | security-scanner | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use when reviewing code changes for security issues — during REVIEW phase or on explicit security, vulnerability, SAST, or secret-scan requests — running available Semgrep/Opengrep, Trivy, and Gitleaks scanners with a self-healing fix loop
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Security Scanner
Hybrid deterministic scanning: CLI tools find vulnerabilities, you fix them.
## When to Use
During REVIEW phase, after code changes are complete. Also invocable on explicit security requests.
## Step 1: Detect Available Tools
Pick the SAST binary (prefer opengrep, fall back to semgrep), then check the rest:
```bash
SAST_BIN="$(command -v opengrep || command -v semgrep || true)"
[ -n "$SAST_BIN" ] && echo "sast: $SAST_BIN" || echo "sast: not installed"
command -v trivy && echo "trivy: available" || echo "trivy: not installed"
command -v osv-scanner && echo "osv-scanner: available" || echo "osv-scanner: not installed (optional)"
command -v gitleaks && echo "gitleaks: available" || echo "gitleaks: not installed"
```
Why opengrep first: it's a fork of Semgrep v1.100.0 (LGPL 2.1) that produces byte-identical JSON for the fields this skill consumes (`check_id`, `extra.severity`, `path`, `start.line`, `extra.message`), uses the same `--config auto` registry (`semgrep.dev/c/auto`), honors `.semgrepignore`, and ships as a single signed binary with no Python dependency. It also returns real `extra.fingerprint` and `extra.lines` values that semgrep gates behind a login.
If **no SAST binary and no trivy** is installed, fall back to LLM-only code review and recommend installation:
- Opengrep (preferred): download the signed binary from https://github.com/opengrep/opengrep/releases or run the official install script
- Semgrep (fallback): `brew install semgrep` or `pip install semgrep`
- Trivy: `brew install trivy`
- Gitleaks: `brew install gitleaks`
## Step 2: Run SAST (Opengrep or Semgrep)
If a SAST binary is available, scan for code vulnerabilities. The `$SAST_BIN` var from Step 1 transparently uses opengrep when present, semgrep otherwise — flags and JSON shape are compatible.
**Important:** Each Bash invocation is a fresh shell. Resolve `SAST_BIN` at the top of every code block below — do not assume Step 1's resolution persists.
**Fast scan (changed files in current branch — prefer this for inner-loop reviews):**
```bash
SAST_BIN="$(command -v opengrep || command -v semgrep || true)"
[ -z "$SAST_BIN" ] && { echo "no SAST binary installed"; exit 0; }
git diff --name-only -z "$(git merge-base HEAD main)..HEAD" | xargs -0 "$SAST_BIN" scan --json --config auto --severity WARNING 2>/dev/null | jq '{count: (.results | length), results: [.results[] | {rule: .check_id, severity: .extra.severity, file: .path, line: .start.line, message: .extra.message}]}'
```
Note: If `merge-base` fails (no main branch), fall back to `git diff --name-only -z HEAD~1 | xargs -0 ...` for the last commit only.
**Full project scan (use for thorough reviews or when explicitly asked):**
```bash
SAST_BIN="$(command -v opengrep || command -v semgrep || true)"
[ -z "$SAST_BIN" ] && { echo "no SAST binary installed"; exit 0; }
"$SAST_BIN" scan --json --config auto --severity WARNING . 2>/dev/null | jq '{count: (.results | length), results: [.results[] | {rule: .check_id, severity: .extra.severity, file: .path, line: .start.line, message: .extra.message}]}'
```
**If output is large (count > 20), filter by severity first:**
```bash
SAST_BIN="$(command -v opengrep || command -v semgrep || true)"
[ -z "$SAST_BIN" ] && { echo "no SAST binary installed"; exit 0; }
"$SAST_BIN" scan --json --config auto --severity ERROR . 2>/dev/null | jq '.results[:20]'
```
## Step 3: Run Trivy (Dependency/CVE Scanning)
If trivy is available, scan for vulnerable dependencies and IaC misconfigurations.
**Dependency scan:**
```bash
trivy fs --scanners vuln,misconfig --format json --severity HIGH,CRITICAL --ignore-unfixed . 2>/dev/null | jq '{count: (.Results // [] | map(.Vulnerabilities // [] | length) | add // 0), results: [.Results // [] | .[].Vulnerabilities // [] | .[] | {pkg: .PkgName, installed: .InstalledVersion, fixed: .FixedVersion, severity: .Severity, cve: .VulnerabilityID, title: .Title}]}'
```
**If Dockerfile exists, also scan the image config:**
```bash
trivy config --format json --severity HIGH,CRITICAL . 2>/dev/null | jq '.Results // []'
```
## Step 3.5: Run OSV-Scanner (Registry-Native Advisories)
If `osv-scanner` is available, run a supplementary scan against [OSV.dev](https://osv.dev), which aggregates GHSA, PyPA, RustSec, Go vulnerability DB, and npm/Maven Central security advisories. OSV often surfaces registry-native advisories before they propagate to Trivy's NVD-anchored data.
**Detection:**
```bash
command -v osv-scanner >/dev/null 2>&1 && echo "osv-scanner: available" || echo "osv-scanner: not installed (optional)"
```
If not installed, document the install path and skip:
```bash
# macOS arm64
curl -L https://github.com/google/osv-scanner/releases/latest/download/osv-scanner_darwin_arm64 -o ~/.local/bin/osv-scanner
chmod +x ~/.local/bin/osv-scanner
```
(Ensure `~/.local/bin` is on your `PATH`, or use `/usr/local/bin/` instead.)
(Linux: replace `darwin_arm64` with `linux_amd64`. macOS Intel: `darwin_amd64`.)
**Scan (recursive directory mode):**
```bash
osv-scanner scan -r --format=json . 2>/dev/null | jq '{count: ([.results[]?.packages[]?.vulnerabilities[]?] | length), results: [.results[]?.packages[]? | {pkg: .package.name, ecosystem: .package.ecosystem, version: .package.version, vulns: [.vulnerabilities[]? | {id: .id, aliases: .aliases, severity: (.database_specific.severity // (.severity[0].score | if . != null then "cvss_vector:\(.)" else null end) // "unknown"), summary: .summary}]}]}'
```
**De-duplicate against Trivy results.** Cross-check the `aliases` field: if a finding's `id` or any alias matches a CVE/GHSA already reported by Trivy in Step 3, treat as duplicate and surface only once. Label OSV-only findings (no Trivy counterpart) under the "Registry-native advisories" subsection of the report.
If `osv-scanner` is not available, this step is skipped silently — no impact on Steps 4-6.
## Step 4: Run Gitleaks (Secret Detection)
If gitleaks is available, scan for hardcoded secrets.
```bash
gitleaks detect --source . --no-banner --report-format json 2>/dev/null | jq '{count: (. | length), results: [.[] | {rule: .RuleID, file: .File, line: .StartLine, description: .Description}]}'
```
## Step 5: Triage and Fix
Present findings as a structured table:
```markdown
## Security Scan Results
### SAST (Opengrep/Semgrep) — N findings
| Severity | File | Line | Rule | Message |
|----------|------|------|------|---------|
### Trivy (Dependencies) — N vulnerabilities
| Severity | Package | Installed | Fixed | CVE | Title |
|----------|---------|-----------|-------|-----|-------|
### OSV-Scanner (Registry-native advisories) — N findings
| Severity | Package | Ecosystem | Version | Advisory ID | Aliases | Summary |
|----------|---------|-----------|---------|-------------|---------|---------|
### Gitleaks (Secrets) — N findings
| Rule | File | Line | Description |
|------|------|------|-------------|
```
**Fix priority:** CRITICAL > HIGH > ERROR > WARNING
For each fixable finding:
1. Fix the issue using your normal editing tools
2. Re-run the specific scanner on the changed file to verify the fix
3. Move to the next finding
**Max 3 fix-rescan iterations** to prevent infinite loops.
## Step 6: Report
After fixing, present a final summary:
- Total findings by tool and severity
- What was fixed (with file:line references)
- What needs human review (and why — e.g., business logic dependency, false positive candidate)
- What was NOT scanned (tools not installed) with install recommendations
## Ignore Files
If false positives are found, help the user configure:
- `.semgrepignore` for Semgrep/Opengrep exclusions (both binaries honor the same filename)
- `.trivyignore` for Trivy exclusions
- `.gitleaksignore` for Gitleaks exclusionsRelated Skills
unified-context-stack
Tiered context retrieval across External Truth (docs), Internal Truth (dependencies), Historical Truth (memory), and Intent Truth (feature specs) with graceful degradation based on installed tools.
supply-chain-investigation
Use when investigating a published supply-chain attack on a registry package (npm, Maven, PyPI, Go, Gradle) — advisory-driven org-wide audit. Triggers on attack-language ("compromised", "malicious", "hijacked", "backdoored", "typosquatted"). NOT for routine CVE scanning — that routes to security-scanner.
skill-scaffold
Emit repo-native seed files (SKILL.md skeleton, routing entry, test snippets) when creating new skills, commands, or plugins
runtime-validation
Use when you need to prove a change actually works through its real interfaces — during REVIEW or on requests like validate the feature, does it work, run e2e, or smoke test — covering browser E2E, API smoke, CLI checks, and a11y audits with graceful tool-degradation
prototype-lab
Produce 3 thin comparable variants of a proposed design with a comparison artifact and mandatory Human Validation Plan
project-verification
Use when you need to run the repo's own declared test/lint/type gate locally and emit pass/fail evidence — during REVIEW, before requesting code review, or on a request to run the tests or verify the build — discovering the gate from CLAUDE.md, Makefile, pyproject, or .verify.yml
product-discovery
Use when starting a new feature or initiative and you need problem context, prior art, and acceptance criteria before design — the DISCOVER phase entry point — pulling Jira/Confluence context and synthesizing a discovery brief to validate problem framing
outcome-review
Use when reviewing a shipped feature's real-world outcome in the LEARN phase — checking adoption, error, or experiment metrics after release, validating ship-time hypotheses, or deciding follow-up work — querying PostHog and creating gated follow-up Jira work
openspec-ship
Use when shipping a completed feature and generating as-built OpenSpec docs before branch finalization
incident-trend-analyzer
On-demand postmortem trend analysis — recurrence grouping, trigger categorization, MTTR/MTTD from canonical docs/postmortems/ corpus
incident-analysis
Use when investigating production symptoms — connection failures, pod crashes/restarts, SIGTERM/OOM errors, latency spikes, Cloud SQL/proxy issues, deployment-correlated errors, ImagePullBackOff, CreateContainerConfigError, or node NotReady events
implementation-drift-check
Use when verifying an implementation still matches its spec or plan — during REVIEW or SHIP, or on demand to check drift, confirm you are still on plan, or run a spec check — surfacing spec deviations, unvalidated assumptions, and untested code paths against Intent Truth