Skip to content

Security Scan

The security-scan pipeline performs a multi-layered code security review combining static pattern matching, git history analysis, dependency auditing, and an AI security-master review. Deterministic scanners run first; their outputs are fed inline to the security-master, which reads the source on a read-only tool surface and produces a curated set of findings. Delivery merges that curated set with a deterministic safety net for uncovered High+ scanner facts. The pipeline delivers findings in SARIF, Markdown, or console format.

Pipeline type: structured

security-scan uses the structured pipeline type: a fixed, deterministic step list -- no LLM decides which steps run. Since p0179d a single security-master agent (the AgenticMaster step) carries the analysis end-to-end over the scanner outputs, replacing the earlier triage / skill-rounds / convergence chain. There is no LLM-based triage and no convergence checking.

Pipeline Steps

# Command What It Does
1 LoadCatalog Pulls and verifies the skill catalog
2 PipelineNameInitializer Stamps the pipeline name for skill routing
3 CheckoutSource Clones repo, optionally scopes to a PR diff or branch
4 SetupRegistryAuth Pre-stages private package-feed credentials for the dependency audit
5-6 BootstrapCheck / BootstrapGate Detects language, framework, dependencies; strict gate on failure
7 LoadContext Loads the project brief from the target's .agentsmith/
8 LoadCodingPrinciples Loads security-principles.md with exclusion rules
9 StaticPatternScan Runs 91 regex patterns across 6 categories against source files
10 GitHistoryScan Scans last 500 commits for secrets in git history via LibGit2Sharp
11 DependencyAudit Runs npm audit / pip-audit / dotnet audit + structural checks
12 SecurityTrend Computes trend from previous SARIF snapshots
13 AnalyzeCode Scout agent maps file structure and dependency graph
14 AgenticMaster Runs the security-master: reads source read-only, triages the scanner facts, emits curated observations
15 MergeMasterFindings Merges the master's curated set with uncovered High+ scanner facts (see below)
16 DeliverFindings Writes output in the requested format(s)
17 SecuritySnapshotWrite Persists SARIF snapshot for trend history
18 SpawnFix Spawns fix jobs for Critical/High findings (skips if auto_fix.enabled: false)

Delivery is the master's curated triage (p0277)

The MergeMasterFindings step sets the delivered findings to the security-master's curated observations plus every High+ deterministic scanner fact the master didn't cover -- refine-with-safety-net. Low/medium scanner noise the master doesn't re-state is suppressed. Collision identity is (file, start line); on collision the master's version wins.

Static Pattern Scan

The StaticPatternScan step runs 91 regex patterns organized into 6 categories. Patterns ship in the agentsmith-skills release tarball alongside skills, and are loaded from {cacheDir}/patterns/*.yaml after the catalog is pulled at boot:

Category Patterns Examples
secrets 27 AWS keys, GitHub tokens, private keys, connection strings
injection 16 SQL injection, command injection, XPath, template injection
ssrf 12 URL construction from user input, DNS rebinding vectors
config 15 Debug mode enabled, permissive CORS, missing security headers
compliance 10 PII logging, missing encryption, weak hashing algorithms
ai-security 11 Prompt injection, unsafe deserialization of model output, API key in prompts

Pattern files are extensible -- contribute upstream via a PR against agentsmith-skills, or override per-deployment via AGENTSMITH_CONFIG_DIR. See Custom Security Patterns for both paths.

Files that self-declare as generated (an <auto-generated> header) are skipped for non-secret static patterns -- injection or config findings in code nobody hand-edits are noise. Secret detection still runs in generated files: a committed credential is live regardless of who wrote the file.

Git History Scan

The GitHistoryScan step uses LibGit2Sharp to scan the last 500 commits for secrets that may have been committed and later removed. A secret found only in git history is reported as Critical -- rotated-away-but-still-in-history is exactly what attackers mine, and it stays exposed even though the current codebase looks clean. A secret still present in the working tree is reported as High.

When a secret is detected, the scanner identifies the secret provider (AWS, GitHub, Stripe, etc.) and includes a revoke URL in the finding so teams can immediately rotate the compromised credential.

Dependency Audit

The DependencyAudit step runs language-specific audit tools and performs structural checks:

  • npm audit for Node.js projects
  • pip-audit for Python projects
  • dotnet audit for .NET projects
  • Structural checks: missing lockfiles, wildcard version ranges, deprecated packages

How the Master Analyzes

The AgenticMaster step loads the security-master skill from the catalog and runs the analysis end-to-end:

  • Read-only review surface (p0278). Scan masters get review tools only -- read, list, grep, tree. There is no run_command and no write tool: the master reviews code; it cannot modify anything or execute anything.
  • Scanner outputs fed inline (p0278). The StaticPatternScan / GitHistoryScan / DependencyAudit / SecurityTrend results are embedded directly in the master's prompt as seeds for its own judgment -- a pattern hit is a lead to read the code at, not a finding to forward.
  • Scan depth is measured (p0279). Coverage is counted as the number of distinct source files the master actually read. If it stays below agent.scan_min_source_reads (config key, default 6), the master is re-prompted once with a full surface inventory and told to review every area. A finding that claims source analysis of a file the master never read is downgraded to a "potential" finding.

The master's methodology ships as the security-master skill in the agentsmith-skills catalog; see Skills Catalog for how to pin or override it.

Delivery: Curated Triage with a Safety Net

The MergeMasterFindings step (p0277) decides what actually ships:

  1. The master's curated observations are the primary delivered set.
  2. Every High or Critical deterministic scanner fact the master's observations don't cover is promoted alongside them -- the safety net. Low/medium scanner noise the master doesn't re-state is suppressed.
  3. Collision identity is (file, start line): when a master observation and a scanner fact point at the same location, the master's version wins.
  4. Read-set merge (p0333): read-set suppression applies only to static-pattern scanner facts. A High+ static-pattern fact in a file the master read and chose not to flag counts as an implicit rejection and is not promoted; if the master never read the file, the fact is promoted. Git-history secrets and dependency CVEs always promote regardless of the read-set -- reading the current source cannot refute a secret in history or a vulnerable dependency version.

Output Formats

The --output flag controls how findings are delivered:

Findings printed to stdout with severity coloring:

[CRITICAL] AWS Access Key in git history — config/aws.json (commit a1b2c3d, 2025-11-03)
          Provider: AWS | Revoke: https://console.aws.amazon.com/iam/home#/security_credentials
[HIGH] SQL Injection in UserRepository.cs:47
       String concatenation in WHERE clause with user-supplied email parameter
[MEDIUM] Missing HttpOnly flag on auth cookie — AuthController.cs:23

Industry-standard Static Analysis Results Interchange Format. Import into GitHub Advanced Security, Azure DevOps, or any SARIF viewer:

{
  "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json",
  "version": "2.1.0",
  "runs": [{
    "tool": { "driver": { "name": "AgentSmith SecurityScan" } },
    "results": [
      {
        "ruleId": "VULN-001",
        "level": "error",
        "message": { "text": "SQL Injection in UserRepository.cs:47" },
        "locations": [{ "physicalLocation": { "artifactLocation": { "uri": "src/Repositories/UserRepository.cs" }, "region": { "startLine": 47 } } }]
      }
    ]
  }]
}

Structured report written to the output directory:

# Security Scan Results
**Date:** 2026-03-26
**Participants:** security-master

## Executive Summary
Delivered 14 findings (master triage + 1 uncovered High scanner fact)
Static patterns: 47 matches | Git history: 2 secrets | Dependencies: 3 vulnerable

## Findings
### [CRITICAL] AWS Access Key in Git History
**Source:** GitHistoryScan | **Commit:** a1b2c3d (2025-11-03)
**Provider:** AWS | **Revoke:** https://console.aws.amazon.com/iam/home#/security_credentials

### [HIGH] SQL Injection in UserRepository.cs
**File:** src/Repositories/UserRepository.cs:47
**Attack vector:** User-supplied email parameter concatenated into SQL WHERE clause...

CLI Examples

# Scan a local repo, console output
agent-smith security-scan --repo .

# Scan with SARIF output for CI integration
agent-smith security-scan --repo . --output sarif --output-dir ./reports

# Scan a specific branch, markdown output
agent-smith security-scan --repo ./my-api --branch feature/auth --output markdown

# Scan only the diff of a pull request
agent-smith security-scan --repo ./my-project --pr 42 --output markdown

# Dry run — show the pipeline without executing
agent-smith security-scan --repo ./my-project --dry-run

# Combine output formats
agent-smith security-scan --repo ./my-project --output sarif,markdown,console --output-dir ./reports

CI/CD integration

Use --output sarif in your CI pipeline and upload the result to GitHub Advanced Security or Azure DevOps. The exit code is non-zero when HIGH or CRITICAL severity findings are present. See GitHub Actions, Azure DevOps, and GitLab CI for ready-to-use pipeline configurations.

Exclusion Rules

The security-principles.md file (loaded by LoadCodingPrinciples) is injected into the security-master's prompt and controls what it filters out. Common exclusions:

  • Test-only code paths
  • Placeholder/example credentials
  • DoS without demonstrated exploit path
  • Path-only SSRF (host not user-controlled)
  • Race conditions without reproducible evidence

Place security-principles.md in your repo's config/skills/security/ directory to customize exclusions per project.

DAST (OWASP ZAP)

When enabled, the pipeline includes a ZAP scan step that tests the running application for runtime vulnerabilities -- XSS, CSRF, auth bypass, header misconfiguration. ZAP runs as a Docker container using the same docker cp pattern as Nuclei.

Three scan types are available: baseline (~2 min, passive), full-scan (~10 min, active injection), and api-scan (~5 min, OpenAPI-aware). Two dedicated skills (dast-analyst and dast-false-positive-filter) process ZAP findings alongside static analysis results.

See Security Scan Configuration for setup.

Auto-Fix

Critical and High findings can be automatically submitted as fix PRs. After the scan completes, findings are grouped by file and category, and separate fix jobs are spawned. Each fix job runs the fix-bug pipeline with a security-specific system prompt.

Auto-fix is opt-in (auto_fix.enabled: false by default) and supports confirmation via Interactive Dialogue before spawning fixes.

Fix PRs follow the standard delivery rule: a run that finishes with red verification opens its PR as a draft (p0300c), so unverified changes never look ready to merge.

See Security Scan Configuration for setup.

Trend Analysis

Git-based security trend analysis tracks findings over time without any external database. Each scan writes structured data to result.md frontmatter, and the SecurityTrend command reads SARIF snapshots from Git history to compute deltas.

Use agent-smith security-trend --project my-api to view the trend from the CLI.

See Security Scan Configuration for setup.