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

$curl -o ~/.claude/skills/security-scanner/SKILL.md --create-dirs "https://raw.githubusercontent.com/damianpapadopoulos/auto-claude-skills/main/skills/security-scanner/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/security-scanner/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How security-scanner Compares

Feature / Agentsecurity-scannerStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/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 exclusions

Related Skills

unified-context-stack

5
from damianpapadopoulos/auto-claude-skills

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

5
from damianpapadopoulos/auto-claude-skills

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

5
from damianpapadopoulos/auto-claude-skills

Emit repo-native seed files (SKILL.md skeleton, routing entry, test snippets) when creating new skills, commands, or plugins

runtime-validation

5
from damianpapadopoulos/auto-claude-skills

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

5
from damianpapadopoulos/auto-claude-skills

Produce 3 thin comparable variants of a proposed design with a comparison artifact and mandatory Human Validation Plan

project-verification

5
from damianpapadopoulos/auto-claude-skills

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

5
from damianpapadopoulos/auto-claude-skills

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

5
from damianpapadopoulos/auto-claude-skills

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

5
from damianpapadopoulos/auto-claude-skills

Use when shipping a completed feature and generating as-built OpenSpec docs before branch finalization

incident-trend-analyzer

5
from damianpapadopoulos/auto-claude-skills

On-demand postmortem trend analysis — recurrence grouping, trigger categorization, MTTR/MTTD from canonical docs/postmortems/ corpus

incident-analysis

5
from damianpapadopoulos/auto-claude-skills

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

5
from damianpapadopoulos/auto-claude-skills

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