Customer story · Energy
50+ developers get confirmed tickets instead of scanner reports, triaged by two AI models
We built a pipeline where two AI models separate real vulnerabilities from scanner noise, so developers only get the tickets that matter.
- Sector
- Energy
- Developers
- 50+
- Duration
- 8 weeks, 2026
- Pipeline
- GitHub Actions
- Scanners
- 3, static and dynamic
The situation
- Three scanners on every pull request: SonarQube on the code, OWASP ZAP and Nuclei on the running app
- Finding vulnerabilities was not the problem. Knowing which were real was.
- The same issue reported more than once, by more than one tool
- With 50+ developers, nobody can read every finding by hand
91%
of static-analysis findings were false positives: 180 real out of 2,116
Ghost Security, 2025
20%
of breaches began with an exploited vulnerability, up 34% in a year
Verizon DBIR, 2025
The architecture
What we built
1. Test the running app, not just the code
- Each pull request deploys the app into a sandbox container in GitHub Actions
- OWASP ZAP and Nuclei attack that copy; SonarQube reads the code
- Nothing is tested against production
2. Ground the model in the real architecture
The triage model sees what the scanner cannot:
- Architecture documents
- Threat models
- The team’s past decisions on similar findings
3. Three outcomes, each one explained
Every finding gets a confidence level and one of:
- Real vulnerability: goes to human review
- False positive: closed with a written reason anyone can audit
- Needs a human: the model is unsure and says so
4. A second model checks the first
- Claude Opus or GPT, through GitHub Models
- One model triages; a second checks every verdict
- Workflow built and compared in LangGraph and Semantic Kernel
5. A person before any ticket
- No ticket without human approval
- Every decision feeds back into the knowledge base
6. One ticket per vulnerability
- Jira is checked for an existing ticket first
- Ten pull requests, one flaw: one ticket
- Each ticket: severity, fix suggestion, owner, confidence
What changed
- Developers get tickets, not scanner reports
- Each ticket confirmed and deduplicated, with a fix, an owner and a confidence level
- Every dismissed finding keeps its written reason
What we learned
Garbage in, garbage out. Grounded in the architecture and past decisions, the model makes calls the team can check.
If you are in the same situation
If your scanners produce more alerts than your team reads, this is what we bring, built on the tools you already run:
- A sandbox environment per pull request in your CI, so dynamic scans test a real running copy
- Your existing scanners wired in, static and dynamic
- A knowledge base from your architecture documents, threat models and past decisions
- A triage workflow with three outcomes and a written reason for every dismissal
- A second model that checks each verdict, on the models you are allowed to use
- Human approval, and a feedback loop into the knowledge base
- Ticket creation in Jira or your tracker, with deduplication
Eight weeks for 50+ developers. A smaller team can start with one scanner and the same triage.
Drowning in scanner alerts?
Tell us about your pipeline and your scanners. We will tell you what to triage first, and what an agent could take on.
The stack
Pipeline and runtime
- GitHub Actions
- Sandbox container
Scanners
- SonarQube
- OWASP ZAP
- Nuclei
Models
- GitHub Models
- Claude Opus
- GPT
Orchestration and retrieval
- LangChain
- LangGraph
- Semantic Kernel
- RAG
Tickets
- Jira
Sources
- Ghost Security, Exorcising the SAST Demons (2025), as reported by Help Net Security, 19 June 2025 Figures consistent across independent coverage of the report.
- Verizon, 2025 Data Breach Investigations Report (April 2025) Figures as reported in Verizon’s announcement of the report and consistent across independent coverage.