Static analysis tools are pattern matchers. That's their strength (fast, deterministic, explainable) and their weakness: a rule that matches string-built SQL can't tell whether the string came from a user or a constant. So you get findings that are technically correct and practically irrelevant, and teams learn to ignore the whole report.
In OpenRouting we keep the scanner as the source of truth and add a review step: Claude, via Amazon Bedrock, looks at each finding with the surrounding code and gives a verdict. This post walks through how that step is built. The design choices matter more than the model.
1. The scanner finds, the model judges
The model never goes looking for vulnerabilities on its own. Semgrep finds them, every finding is normalised into one schema (rule id, scanner, severity, CWE, file, line range, snippet, message), and only then does the model review it. That gives two properties we care about:
Every finding traces back to a deterministic rule.…