alexpermiakov/SAST Triage

Triage SAST findings (SARIF 2.1.0) with a bounded LLM agent and an evidence-keyed verdict cache.

View on GitHub

Trust Signals

Scorecard Score
not yet scored
Maintenance Recency
Stale
License
None
namedescriptionrequireddefault
providerLLM API shape: anthropic for Claude's native API, openai for anything OpenAI-compatible. Leave empty (the default) and base-url selects it for you""
modelModel name — always required (e.g. claude-sonnet-5 for anthropic, qwen2.5-coder:7b for openai)yes
base-urlOpenAI-compatible API base URL; required when provider is openai (e.g. http://localhost:11434/v1). No default: the tool only ever talks to the endpoint you name""
api-keyAPI key for whichever provider is selected — routed to ANTHROPIC_API_KEY or OPENAI_API_KEY to match. Self-hosted endpoints need none. Prefer this over the provider-specific inputs below""
anthropic-api-keyProvider-specific alternative to api-key, for provider: anthropic. Wins over api-key when both are set""
openai-api-keyProvider-specific alternative to api-key, for hosted OpenAI-compatible endpoints. Wins over api-key when both are set""
sarif-fileSARIF 2.1.0 input produced by your scannerfindings.sarif
repoRepository root the findings refer to.
scopeWhat to triage: full (every finding in the SARIF) or diff (only findings in files changed since base-ref). Set it from your trigger — pull_request wants diff, schedule and workflow_dispatch want full. Never inferred.full
base-refBase to diff against when scope is diff, e.g. origin/main. Needs fetch-depth: 0 on checkout""
modeWhether this run can fail the build: enforce (exit 3 on exploitable findings in scope), report (advisory), or baseline (triage everything, gate nothing — seeding a fresh cache).enforce
cache-writeWhat to do with the updated cache: branch (commit to the branch being built — use on PRs), pr (open/refresh one review PR — use when seeding), or none (artifact only). Fork PRs cannot push, and fall back to none automatically.none
cacheVerdict cache file (commit it to git).sast-triage/cache.json
reportMarkdown report output (complete; no size cap)triage-report.md
digestByte-bounded digest of the report, safe to publish to the step summary (1 MiB cap) or a PR/issue body (65,536 chars). Empty = skip.triage-digest.md
digest-bytesSize cap for the digest; overflow is dropped by priority (benign first, exploitable last)50000
summaryRun headline plus one bounded verdict table (15 rows max). Used verbatim as the seed PR body, which sits above a cache diff carrying every verdict in full. Empty = skip.triage-summary.md
triaged-sarifVerdict-annotated copy of the input SARIF — benign findings gain a SARIF suppression, nothing is ever deleted. Upload it to Code Scanning or feed it to DefectDojo. On by default; empty = skip.triaged.sarif
effortTriage depth per finding: small | medium | large | xlargemedium
max-findings-budgetMax findings triaged by LLM per run (0 = unlimited)50
parallelFindings triaged concurrently4
create-issuesFile GitHub issues for exploitable findings (needs an issues-writable token)false
pr-commentsPost exploitable verdicts as inline comments on the PR diff (needs pull-requests: write). Auto-detects the PR number on pull_request triggers.false
github-repoowner/name for issue creation; defaults to the current repository""
github-tokenToken used for issue creation when create-issues is true${{ github.token }}
link-baseBase URL for clickable evidence links, e.g. https://github.com/owner/repo/blob/<sha>""
extra-argsExtra CLI flags appended verbatim, e.g. "-max-iterations 15 -issue-label security"""

no outputs