AI-Powered Vulnerability Triage Using GitHub Security Lab Taskflow Agent

github · Tech · 2026 · source Agentic: yes · promotional bias: low · source-backed · extracted with prompt 0.5.4 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Security alert triage

GitHub Security Lab needed to triage large volumes of CodeQL code scanning alerts where false positives often depend on fuzzy code semantics that humans can spot but static rules struggle to encode.

Constraints:

Architecture

GitHub Security Lab built taskflows as YAML-defined sequences of LLM tasks. A taskflow fetches CodeQL alert results, runs templated tasks across alerts asynchronously, gathers scoped notes into a database, audits likely false-positive causes, and generates GitHub issues or reports with source references. MCP servers handle deterministic file fetching, searching, workflow trigger extraction, and other programmatic checks. The LLM, mostly Claude Sonnet 3.5 in the reported experiments, handles fuzzy semantic reasoning such as whether authentication or sanitization makes an alert non-exploitable.

Diagram confidence: explicit (topology described by the source).

flowchart LR
  codeql-alert-source["codeql-alert-source"] --> taskflow-runner["taskflow-runner"]
  taskflow-yaml-definitions["taskflow-yaml-definitions"] --> taskflow-runner["taskflow-runner"]
  taskflow-runner["taskflow-runner"] --> mcp-tool-servers["mcp-tool-servers"]
  taskflow-runner["taskflow-runner"] --> llm-triage-reasoner["llm-triage-reasoner"]
  taskflow-runner["taskflow-runner"] --> audit-notes-database["audit-notes-database"]
  mcp-tool-servers["mcp-tool-servers"] --> source-code-repository["source-code-repository"]
  source-code-repository["source-code-repository"] --> llm-triage-reasoner["llm-triage-reasoner"]
  llm-triage-reasoner["llm-triage-reasoner"] --> audit-notes-database["audit-notes-database"]
  llm-triage-reasoner["llm-triage-reasoner"] --> report-generation-step["report-generation-step"]
  audit-notes-database["audit-notes-database"] --> report-generation-step["report-generation-step"]
  report-generation-step["report-generation-step"] --> human-security-auditor["human-security-auditor"]
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
codeql-alert-source Produces code scanning alerts over selected open source repositories. taskflow-runner
taskflow-yaml-definitions Declarative YAML task sequences and templated prompts for triage workflows. taskflow-runner
taskflow-runner Executes tasks in sequence or batch for-loop style, passing results between steps. codeql-alert-source, taskflow-yaml-definitions, mcp-tool-servers, llm-triage-reasoner, audit-notes-database
mcp-tool-servers Programmatic tools for deterministic file fetching, search, trigger checks, and other code facts. taskflow-runner, source-code-repository
source-code-repository Target project source code inspected during alert triage. mcp-tool-servers, llm-triage-reasoner
llm-triage-reasoner LLM that evaluates fuzzy code semantics, exploitability, access control, sanitization, and false-positive causes. taskflow-runner, source-code-repository, audit-notes-database, report-generation-step
audit-notes-database Intermediate state store for task notes, debugging, resume, and task-level iteration. taskflow-runner, llm-triage-reasoner, report-generation-step
report-generation-step Creates triage reports or GitHub issues with conclusions and supporting references. llm-triage-reasoner, audit-notes-database, human-security-auditor
human-security-auditor Verifies generated vulnerability reports and decides follow-up. report-generation-step

Data flow

CodeQL produces code scanning alerts over selected repositories. The taskflow agent reads YAML task definitions, fetches alert and source context using basic tools, iterates through alerts with templated prompts, records audit notes to a database after each task, delegates deterministic code facts to MCP tools, asks the LLM to reason about exploitability and false-positive checks, and emits a report or GitHub issue containing the verdict and supporting source references for human verification.

4 supporting quotes
“Taskflows are YAML files that describe a series of tasks that we want to do with an LLM.”article, stated
“The seclab-taskflow-agent framework takes care of running the tasks one after another and passing the results from one task to the next.”article, stated
“Once the task is completed, the notes are serialized to a database which the next task can then append their notes to when it is done.”article, stated
“When triaging the alerts, the LLMs were only given tools to perform basic file fetching and searching.”article, stated

Why this architecture

The team used taskflows rather than a single prompt because complex security analysis can skip steps and exceed context windows. The database-backed note model makes failures resumable and debugging granular. MCP tools handle deterministic code facts because LLMs were inconsistent at extracting triggers and privilege context, while LLMs remain useful for human-like fuzzy reasoning over access checks, sanitizers, and exploitability.

4 supporting quotes
“We use tasks instead of one big prompt because LLMs have limited context windows, and complex, multi-step tasks often are not completed properly.”article, stated
“taskflows are useful to provide a way for us to control and debug the task”article, stated
“we also noticed some inconsistencies due to the non-deterministic nature of the LLM.”article, stated
“moving most of the tasks that can easily be done programmatically to MCP server tools while leaving the more complex logical reasoning tasks”article, stated

Models used: Claude Sonnet 3.5 · LLM taskflows · MCP · CodeQL · GitHub Issues

Scale

Alternatives considered (roads not taken)

One large prompt for the whole triage workflow

Rejected because: Multi-step security tasks are often incomplete in one prompt and hard to debug.

“complex, multi-step tasks often are not completed properly. Some steps are frequently left out”article, stated

Ask the LLM to gather deterministic workflow facts

Rejected because: The LLM inconsistently recorded workflow trigger events and privilege conclusions.

“the LLM sometimes would only record a subset of the events that trigger the workflow”article, stated
“it would sometimes make inconsistent conclusions about whether the trigger runs the workflow in a privileged context or not.”article, stated

End-to-end autonomous exploit validation

Rejected because: The team only generates bug reports for human verification and does not give the LLM runtime environments to validate exploits.

“The taskflows do not perform an “end-to-end” analysis, but rather produce a bug report with all the details and conclusions”article, stated
“We did not instruct the LLM to validate the results by creating an exploit nor provide any runtime environment for it to test its conclusion.”article, stated

Patterns

prompt-chaining (workflow)

Security triage is decomposed into YAML-defined tasks rather than one broad prompt.

“we first want to fetch the code scanning results. Then, for each result, we may have a list of tasks that we need to check.”article, stated

tool-use-orchestration (agent architecture)

MCP servers perform deterministic file and code-fact tasks while the LLM handles semantic triage.

“use MCP servers to perform tasks that are well suited for conventional programming.”article, stated

durable-execution (workflow)

Task notes are serialized after each step so the workflow can be debugged, reused, and resumed task by task.

“each of the information gathering tasks is independent of each other and does not need to read each other’s notes.”article, stated
“storing results of each task in a database, we can easily separate out part of a taskflow and run it separately.”article, stated

human-in-the-loop-gate (security)

The agent produces reports with enough evidence for human auditors to verify and decide follow-up.

“To ensure that the generated report has sufficient information for a human auditor to make a decision”article, stated

Tradeoffs

Generate reports instead of autonomous final judgments.

Chose Bug reports with details and conclusions over End-to-end exploit validation or fully automatic disclosure.

Rationale: Security decisions remain with human auditors while the agent removes repetitive triage work.

“produce a bug report with all the details and conclusions so that we can quickly verify the results.”article, stated

Use notes as a bag of information.

Chose Independent scoped tasks and serialized audit notes over Every task reading all prior context.

Rationale: Independent notes keep tasks focused and avoid distracting later tasks with unrelated context.

“This helps each task to focus on its own scope without being distracted by previously collected information.”article, stated

Limit the tools available during triage.

Chose Basic file fetching and searching plus MCP programmatic checks over Full static/dynamic analysis toolchain in the agent loop.

Rationale: The experiment isolates LLM taskflow triage on top of CodeQL alerts rather than giving the model broad execution powers.

“We have not used any static or dynamic code analysis tools other than to generate alerts from CodeQL.”article, stated

Gotchas (what bit them)

LLMs are unreliable for deterministic code facts.

Root cause: Non-determinism caused missing trigger events and inconsistent privilege-context conclusions.

Resolution: Move those checks into MCP server tools and reserve the LLM for fuzzy semantic reasoning.

“Since these information and checks can easily be performed programmatically, we ended up creating tools in the MCP servers”article, stated
“This led to a much more consistent outcome.”article, stated

Static analyzers miss human-obvious access-control and sanitizer context.

Root cause: Checks come in many forms without easy code patterns; custom sanitizers and unreachable sources produce false positives.

Resolution: Use LLM tasks to reason about attacker reachability, authentication checks, sanitizers, and exploitability indicators.

“These access control checks come in many different forms without an easily identifiable code pattern to match”article, stated
“Custom or unrecognized sanitization functions (e.g. using regex) that the SAST-tool cannot verify.”article, stated

Evaluation

The team evaluated taskflows by applying them to selected CodeQL rules over open source repositories, checking whether they removed false positives, generated human-verifiable reports, and led to confirmed real vulnerabilities. They also improved prompts based on observed false-positive patterns.

Metrics: real vulnerabilities discovered · false positives removed · human-verifiable report completeness · CodeQL rules tested · task consistency after MCP delegation

3 supporting quotes
“We have identified a number of real, exploitable vulnerabilities.”article, stated
“we were able to remove false positives in the CodeQL queries quickly.”article, stated
“Based on these false positives, the prompts in the relevant taskflow or even in the active personality were extended and adjusted.”article, stated

Outcomes

The disclosed scale is a large number of code scanning alerts, a few CodeQL rules over a couple of months, and approximately 30 vulnerabilities found since August.

3 supporting quotes
“many (~30) real-world vulnerabilities since August, many of which have already been fixed and published.”article, stated
“Both the seclab-taskflow-agent and seclab-taskflows repos are open source, allowing anyone to develop LLM taskflows to perform similar tasks.”article, stated
“This led to a much more consistent outcome.”article, stated