agentgg
v0.1.2
Published
Agentic SAST scanner — white box, CI-ready, multi-provider. Reasoning where regex falls short.
Maintainers
Readme
agentgg
Agentic SAST. White box. CI ready.
agentgg is an agentic SAST scanner. Its agents reason about your code. They follow imports, check the call graph, and confirm findings before flagging, instead of pattern-matching the way traditional SAST does. 100+ official agents cover security vulnerabilities, coding anti-patterns, and codebase recon; the catalog auto-downloads on first scan from agentgg-dev/agentgg-agents. Run on your full repo or on a git diff for PR reviews. Each agent runs in one of three modes: file, walker, or hunt. Interrupted scans resume on re-run: only new or changed files hit the LLM again.
agentgg.dev · Agents catalog · Report a security issue
Table of Contents
- Install
- Quick start
- How agents work
- Three execution modes
- Providers
- Examples
- GitHub Actions
- Report format
- Commands
- Scan flag reference
- License
Install
npm install -g agentggFrom source:
git clone https://github.com/agentgg-dev/agentgg
cd agentgg
pnpm install
pnpm --filter agentgg build:bundle
pnpm --filter agentgg link --globalRequires Node.js 20+ and pnpm 9+. See CONTRIBUTING.md for the dev workflow.
Quick start
agentgg init # one-time: pick a provider, paste a key
agentgg scan ./src --validate -o ./out # scan everything, validate findings
agentgg scan ./src --diff origin/main...HEAD --validate -o ./out # PR-style: scan only what changed
agentgg status ./out # what got found / validated / when
agentgg view ./out # browse findings in a local web UI
agentgg scan ./src --serve -o ./out # scan, then boot the UI when doneFindings land in ./out/:
out/
├── summary.md ← human report
├── findings/... ← one .md per finding (GHSA-shaped)
└── state/ ← what `status` and `revalidate` read
├── scan.json ← root path + timestamps
├── runs/<id>.json ← one per scan / revalidate
└── files/<path>.json ← FileRecord per scanned source fileThe state/ directory is what makes resume, status, and revalidate work. Re-running scan with the same -o skips files that haven't changed. Different -o = fresh scan.
How agents work
Every agent is a self-contained markdown file with YAML frontmatter:
---
slug: sql-injection
name: SQL Injection
description: String-concatenated SQL queries.
mode: file # or "hunt"
noiseTier: normal
filePatterns:
- "**/*.{ts,js,py,rb,go}"
references:
- CWE-89
---
You are reviewing source code for SQL injection. Look for queries
built by string concatenation, template interpolation, or unescaped
substitution. ...The same schema applies whether the agent lives in:
- Official catalog (
~/.agentgg/agentgg-agents/): downloaded on first scan from agentgg-dev/agentgg-agents; refresh withagentgg agents update - User-installed (
~/.agentgg/agents/custom/):agentgg agents add ./my-agent.md - Per-scan: pass a
.mdfile, directory, or.txtlist to-t/--template
Three execution modes
Each agent declares its own mode. The framework dispatches accordingly.
mode: file: one LLM call per (agent, matching file). No tools. Cheap, predictable:
sql-injection,command-injection,hardcoded-secrets, …
mode: walker: anchored agentic investigation. The walker enumerates files matching the agent's filePatterns, the agent's preFilter regexes narrow to "candidates" with line hits, then each batch of candidates gets one tool-enabled session:
openclaw-audit-allowlist-identity-walker: anchored allowlist-bypass investigation
mode: hunt: one tool-enabled session per agent across the whole repo. The agent uses Read/Glob/Grep to discover its own files. Good for cross-file logic and CVE-pattern hunts:
missing-access-control: IDOR / auth-middleware coverage across handlersopenclaw-audit-allowlist-identity-hunter: project-specific mutable-identity allowlist bypass
All three modes run side-by-side in one scan. Hunt agents run first (heaviest), then walker, then file agents.
Providers
agentgg init writes credentials to ~/.agentgg/config.json. Scan state is per-output-dir and unrelated to this file.
| Provider | Credential |
|---|---|
| Anthropic | API key (sk-ant-api...) or OAuth (sk-ant-oat..., Claude Pro/Max) |
| OpenAI | API key |
| Ollama | local URL |
| AWS Bedrock | AWS credentials (env / ~/.aws/credentials / IAM role) |
All providers support all three agent modes. Hunt and walker are multi-step and tool-using, so finding quality scales with model quality.
AWS Bedrock
agentgg init --provider bedrock --region us-east-1 walks you through setup. agentgg picks up your existing AWS credentials. Anything that works with the AWS CLI (env vars, aws configure, SSO, IAM role) works here.
Two things to know:
- Inference profiles are required for newer Claude models. Default uses a US profile (
us.anthropic.*); EU/APAC useeu.*/apac.*. Override at init time. - Bedrock has no free tier. Set a CloudWatch billing alarm before scanning large repos.
Examples
Pick which agents to run
Run the default agent set (~/.agentgg/agentgg-agents/base/):
agentgg scan ./src -o ./outEvery scan makes LLM calls; cost scales with files × agents × phases. The biggest levers are scoping the scan (--diff, --only, --exclude, --max-file-size) and picking which agents run (-t). Ollama runs locally for free. --concurrency controls parallelism, not total cost.
A single slug:
agentgg scan ./src -t sql-injection -o ./outMultiple slugs, comma-separated within one -t:
agentgg scan ./src -t sql-injection,hardcoded-secrets,command-injection -o ./outA custom .md agent on disk:
agentgg scan ./src -t ./my-agents/path-traversal.md -o ./outA .txt list file (one slug or path per line):
agentgg scan ./src -t ./agents.txt -o ./outAdd validation
The validation phase is a second-pass LLM call per finding that re-reads the source and classifies as confirmed / false-positive / out-of-scope / uncertain. Off by default. Opt in:
agentgg scan ./src -t sql-injection --validate -o ./outEach finding gets a validation section in its markdown file and a verdict count in summary.md.
Use a scope file to mark out-of-scope findings
Pass any text file the validator should consult as scope context (your security policy, an audit-scope doc, internal notes, etc.). Without --scope, the out-of-scope verdict is withheld. The model would just be guessing.
agentgg scan ./src --validate --scope ./scope.md -o ./outScore findings
Add --score during scan, or run agentgg score ./out afterward, to attach a CVSS 3.1 severity to each finding.
agentgg scan ./src --validate --score -o ./outRe-run only the validation phase
Detect once, validate later (or with a different model / scope):
agentgg scan ./src -t sql-injection -o ./out # detect only
agentgg revalidate ./out # validate everything pending
agentgg revalidate ./out --scope ./scope.md # re-classify with scope
agentgg revalidate ./out --force # re-classify everythingForce a fresh run
Resume is automatic. To bypass the cache:
agentgg scan ./src -t sql-injection -o ./out --rescan # re-analyze every file
agentgg scan ./src -t sql-injection --validate --revalidate-all -o ./outScan only what changed
--diff <commit> scopes the scan to a specific change set. It accepts whatever git accepts (a bare ref or a range), and the dots determine the semantic:
| Form | What it means | Use when |
|---|---|---|
| --diff <commit> | That commit's own changes (parent → commit) | Reviewing a single commit |
| --diff a..b | Tip-to-tip diff between two refs | You want the literal difference, even if a has advanced |
| --diff a...b | Merge-base of a and b → b | Reviewing a PR (matches GitHub's "Files changed" tab) |
How agents behave under --diff:
- file- and walker-mode agents: candidate file lists are intersected with the changed-file set, so unchanged files cost zero LLM calls.
- hunt-mode agents: still run whole-repo, but the commit message + patch is injected into the prompt as a focus hint. Tools stay unrestricted so the hunter can chase callers and imports outward for context.
# Review just the latest commit
agentgg scan ./src --diff HEAD -o ./out
# PR review against main (three dots, recommended)
git fetch origin main
agentgg scan ./src --diff origin/main...HEAD -o ./out
# Reviewing someone else's PR
git fetch origin pull/123/head:pr-123
git checkout pr-123
agentgg scan ./src --diff origin/main...HEAD -o ./out
# Combine with a template
agentgg scan ./src -t sql-injection --diff origin/main...HEAD -o ./outThe --diff value is part of each agent's resume scope. Changing it (or rebasing so the merge base moves) invalidates resume and re-runs the agent.
Patches larger than 64 MB (typically vendored-code or generated-file commits) are rejected for hunt agents. Narrow the scan or review them manually.
Inspect scan state
agentgg status ./out # human-readable
agentgg status ./out --json # machine-readableOutput includes: scanned root, file counts (analyzed / validated / pending), total findings, verdict breakdown, and recent runs.
agentgg status ./out
# Scan state: /path/to/out
# Root: /path/to/src
# Files tracked: 37
#
# Status
# analyzed: 30
# validated: 30
# pending: 7
#
# Findings
# total: 12
# validated: 12/12
# verdicts: confirmed=8, false-positive=4
#
# Recent runs (3 total)
# 20260514001435-4e8b5e55 scan done 88.2s files: 37 findings: 12
# ...Limit what gets scanned
Override the default glob exclusions / restrict to specific paths:
agentgg scan ./src --exclude "**/migrations/**" --exclude "vendor/**" -o ./out
agentgg scan ./src --only "src/api/**/*.ts" --only "src/handlers/**/*.ts" -o ./out
agentgg scan ./src --max-file-size 200 -o ./out # skip files larger than 200 KBThe walker auto-skips lockfiles, minified bundles, binary assets, node_modules, dist, .git, and the scan-results directory regardless of flags.
Use a one-off credential or model without saving it
Useful for CI runs where credentials come from secrets, not a saved config.
agentgg scan ./src \
--provider anthropic \
--api-key $ANTHROPIC_API_KEY \
--model claude-opus-4-7 \
-o ./out--api-key, --oauth-token, --base-url, --region, and --model all work as one-shot overrides. Each is scoped to its provider; passing one that doesn't apply (e.g. --region with --provider openai) is a hard error, not a silent ignore.
Manage agents
agentgg agents list # table of built-ins + custom
agentgg agents list --json # machine-readable
agentgg agents info sql-injection # show prompt + frontmatter
agentgg agents add ./my-agent.md # install into ~/.agentgg/agents/custom/
agentgg agents add ./agents-dir/ # install every .md in a dir
agentgg agents remove my-agent # uninstall by slug
agentgg agents lint # lint installed official tree
agentgg agents lint ./agentgg-agents # lint an arbitrary tree (pre-commit-friendly)GitHub Actions
Run agentgg on every pull request, scoped to the diff:
# .github/workflows/agentgg.yml
name: agentgg PR review
on:
pull_request:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # required so --diff can compute the merge base
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install -g agentgg
- run: |
agentgg scan . \
--diff ${{ github.event.pull_request.base.sha }}...${{ github.sha }} \
--validate \
-o ./scan-results
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: agentgg-findings
path: ./scan-resultsStore your provider credential as a repo secret (Settings → Secrets and variables → Actions). The example uses Anthropic. Swap ANTHROPIC_API_KEY for OPENAI_API_KEY (and add --provider openai) for OpenAI, or follow the AWS Bedrock section for Bedrock.
Findings land in the agentgg-findings workflow artifact for download. To block merges on confirmed findings, parse ./scan-results/summary.md (or the per-finding files in findings/) and exit 1 from a follow-up step.
Report format
Each finding is a markdown file under ./out/findings/, GHSA-shaped:
# <title>
**Agent:** `sql-injection`
**Vuln class:** `sql-injection`
**File:** `src/login.ts`
**Lines:** 12–14
**Confidence:** 90%
**Severity:** High (CVSS 7.5)
**Validation:** `confirmed`
### Summary
One sentence stating the issue + impact.
### Details
Full analysis with code excerpts.
### PoC
Concrete reproduction (HTTP request, payload, command).
### Impact
Vulnerability class, who's affected, what an attacker gets.
### Validation
**Verdict:** `confirmed`
Short reasoning citing the unsafe code element.
### References
- CWE-89summary.md aggregates: counts per agent, validation verdict breakdown, links to each finding.
Commands
| Command | Status |
|---|---|
| agentgg init | ✅ Anthropic API key + OAuth, OpenAI, Ollama, Bedrock; merges new providers |
| agentgg scan <path> | ✅ file + walker + hunt mode, --template, --diff, --validate, --scope, resume |
| agentgg status [output-dir] | ✅ reads <output>/state/, human or --json |
| agentgg revalidate [output-dir] | ✅ re-runs validation against persisted findings |
| agentgg score [output-dir] | ✅ standalone CVSS 3.1 scoring pass over persisted findings |
| agentgg view [output-dir] | ✅ serves the bundled Next.js viewer over a local port |
| agentgg agents list | ✅ table or --json; official + user-installed |
| agentgg agents info <slug> | ✅ |
| agentgg agents add <file-or-dir> | ✅ installs into ~/.agentgg/agents/custom/ |
| agentgg agents remove <slug> | ✅ |
| agentgg agents update | ✅ downloads / refreshes ~/.agentgg/agentgg-agents/ from the agentgg-agents repo |
| agentgg agents lint [path] | ✅ slug uniqueness + filename == slug for the official tree |
| agentgg config | ✅ secrets masked |
Run agentgg <command> --help for the full flag list on any subcommand.
Scan flag reference
-t, --template <value> slug, .md path, directory, or .txt list file;
comma- or whitespace-separated; repeatable
-o, --output <path> output directory (default ./scan-results/)
--validate run a second-pass validation phase per finding
--scope <path> scope file the validator consults (enables `out-of-scope`)
--rescan re-analyze files even if a prior run covered them
--revalidate-all re-validate findings that already have a verdict
--diff <commit> scope scan to a commit or range; file/walker agents only see touched files, hunt agents receive the patch as a focus hint (accepts `<ref>`, `a..b`, or `a...b`)
--concurrency <n> parallel files per agent (default 5)
--exclude <pattern> glob to exclude (repeatable; additive)
--only <pattern> restrict scan to matching globs (repeatable)
--max-file-size <kb> skip files larger than this (default 500)
--provider <name> anthropic | openai | ollama | bedrock (overrides config default)
--api-key <key> one-shot API key for anthropic / openai (not persisted)
--oauth-token <token> one-shot Anthropic OAuth token (not persisted)
--base-url <url> one-shot Ollama base URL (not persisted)
--region <name> one-shot AWS region for Bedrock (not persisted)
-v, --verbose verbose outputLicense
agentgg is licensed under the Apache License, Version 2.0. See LICENSE for the full text and NOTICE for attribution.
