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

The app runs in a sandbox where ZAP and Nuclei attack it. Two models triage every finding against the architecture, and a person approves before anything reaches Jira.

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

  1. Ghost Security, Exorcising the SAST Demons (2025), as reported by Help Net Security, 19 June 2025 Figures consistent across independent coverage of the report.
  2. Verizon, 2025 Data Breach Investigations Report (April 2025) Figures as reported in Verizon’s announcement of the report and consistent across independent coverage.