Security and platform engineering teams often face thousands of raw SAST findings per scan. Manual triage is slow, inconsistent, and prone to alert fatigue. This prompt ingests raw SAST output with code context, deduplicates related findings, filters likely false positives with explicit reasoning, and ranks the remaining issues by exploitability and business impact. Use it when you need a structured, repeatable first-pass triage that integrates into your vulnerability management workflow. It is designed for teams that already have a SAST tool in CI/CD and need to reduce the queue of findings before human review.
Prompt
SAST Finding Severity Triage Prompt Template

When to Use This Prompt
A practical guide for security teams to integrate automated SAST triage into their vulnerability management workflow.
The ideal user is a DevSecOps engineer or application security specialist who can provide the raw SAST output, the relevant code snippets, and a defined [RISK_LEVEL] threshold for escalation. The prompt requires that each finding be accompanied by its source code context; without it, the model cannot reliably distinguish a true positive from a false positive. You should also supply a [CONTEXT] block describing the application's business function, data sensitivity, and exposure level, as this directly informs the business impact ranking. Do not use this prompt for runtime vulnerability data, penetration test reports, or findings without associated code snippets. It is not a replacement for a SAST tool, but a force-multiplier for the triage step that follows a scan.
Before putting this into production, you must establish a ground-truth baseline. Run the prompt against a set of manually triaged findings and measure agreement on severity classification, false-positive filtering, and deduplication. A common failure mode is the model accepting a sanitized input as safe when the sanitization function itself is flawed; always include the implementation of any called validation or encoding function in the [CODE_SNIPPETS] input. Another failure mode is the model over-prioritizing findings based on CWE severity alone without considering the application's specific exposure. Mitigate this by being precise in the [CONTEXT] block about what an attacker could actually reach. The next step is to wire this prompt into an automated harness that validates the output schema, logs every triage decision for audit, and routes high-severity findings for mandatory human review.
Use Case Fit
Where the SAST Finding Severity Triage prompt works, where it fails, and the operational preconditions required before deploying it into a production triage pipeline.
Good Fit: High-Volume SAST Pipelines
Use when: Your CI/CD pipeline generates hundreds or thousands of SAST findings per scan, and manual triage is the bottleneck. The prompt excels at deduplication, initial severity ranking, and filtering obvious false positives before a human ever looks at the queue. Guardrail: Always route findings above a severity threshold (e.g., Critical/High) for mandatory human review regardless of the model's classification confidence.
Bad Fit: Novel Zero-Day Analysis
Avoid when: The finding involves a novel exploit technique, a zero-day vulnerability class, or a custom framework with no public documentation. The model will default to pattern-matching against known vulnerability types and may misclassify genuinely new attack vectors. Guardrail: Escalate findings where the model's reasoning references only generic CWE descriptions without code-specific evidence to a senior security engineer.
Required Input: Code Context Beyond the Finding
Risk: Feeding only the SAST tool's line-number reference without surrounding code, data flow paths, or caller context produces unreliable severity assessments. The model needs to see how the flagged code is actually invoked. Guardrail: Bundle each finding with the full function body, relevant imports, and any sanitizer or validator functions in the same file. Do not send isolated single-line snippets.
Operational Risk: Severity Drift Over Time
What to watch: As your codebase evolves, the model's severity calibration can drift. A finding class that was correctly marked Critical last quarter may now be over-flagged due to new defensive layers the model doesn't know about. Guardrail: Run a monthly calibration pass against a golden set of 50 manually triaged findings and track precision/recall per severity level. Retune the prompt's severity definitions when drift exceeds 10%.
Bad Fit: Compliance-Only Scanning Workflows
Avoid when: The SAST scan exists solely to satisfy a compliance checkbox (e.g., PCI DSS, SOC 2) and every finding must be documented with a fixed disposition workflow. The prompt's false-positive filtering could accidentally suppress findings that auditors expect to see in the raw report. Guardrail: Maintain a separate compliance queue that receives all raw findings. Use the prompt's output as a triage aid, not as a filter that removes records from the audit trail.
Required Input: SAST Tool Rule Metadata
Risk: Without the SAST rule ID, rule description, and confidence metadata, the model cannot distinguish between a high-precision SQL injection rule and a noisy best-practice warning. This leads to uniform severity inflation. Guardrail: Always include the tool name, rule ID, rule severity, and rule confidence in the prompt input. Use this metadata as a cross-check: if the model's severity deviates significantly from the tool's own rating, flag the finding for human review.
Copy-Ready Prompt Template
A reusable prompt with square-bracket placeholders for ingesting raw SAST findings, deduplicating issues, filtering false positives, and ranking true positives by exploitability and business impact.
The following prompt template is designed to be copied directly into your AI harness. It accepts a batch of raw SAST findings, relevant code context, and your organization's triage rules. The model is instructed to deduplicate related findings, filter likely false positives with explicit reasoning, and rank the remaining true positives by exploitability and business impact. Every placeholder is enclosed in square brackets and must be replaced with real data before execution. The output is a structured JSON object that can be validated and ingested by your vulnerability management system.
textYou are a senior application security engineer triaging static analysis (SAST) findings for a production application. Your goal is to reduce alert fatigue by deduplicating related findings, filtering false positives with clear reasoning, and ranking true positives by risk. ## INPUT - **SAST Findings:** [SAST_FINDINGS_JSON] - **Code Context:** [CODE_CONTEXT_SNIPPETS] - **Application Profile:** [APPLICATION_PROFILE] - **Triage Rules:** [TRIAGE_RULES] ## INSTRUCTIONS 1. **Deduplicate:** Group findings that share the same root cause, code location, or data flow path. For each group, select the most representative finding and note the duplicates. 2. **False Positive Analysis:** For each unique finding, determine if it is a false positive. A finding is a false positive if: - The data path is blocked by a sanitizer, validator, or guard that the scanner did not model. - The vulnerable code is unreachable in the application's runtime configuration. - The finding relies on an incorrect assumption about the code's behavior. Provide a concise reason for every false positive classification. 3. **Severity Triage:** For each true positive, assign a final severity based on the [TRIAGE_RULES]. Consider: - **Exploitability:** Attack vector, attack complexity, privileges required, user interaction. - **Business Impact:** Data sensitivity, system criticality, blast radius. Override the scanner's original severity if warranted. 4. **Ranking:** Sort all true positives from highest to lowest risk. ## OUTPUT_SCHEMA Return a single JSON object with the following structure: { "findings": [ { "id": "string (original finding ID)", "title": "string", "original_severity": "string", "final_severity": "string (Critical|High|Medium|Low|Info)", "is_false_positive": boolean, "false_positive_reason": "string | null", "duplicate_of": "string | null (ID of the representative finding)", "exploitability_assessment": "string", "business_impact": "string", "remediation_priority": "integer (1 = highest)" } ], "summary": { "total_raw_findings": integer, "deduplicated_count": integer, "false_positives_count": integer, "true_positives_count": integer, "highest_risk_finding_id": "string" } } ## CONSTRAINTS - Do not invent vulnerabilities or code that is not present in the input. - If the code context is insufficient to make a determination, set `is_false_positive` to false and note the missing context in the assessment. - Never downgrade a finding without a specific, evidence-backed reason. - If [TRIAGE_RULES] specify a mandatory escalation for certain conditions, reflect that in the `final_severity`.
To adapt this template for your pipeline, replace each placeholder with real data. [SAST_FINDINGS_JSON] should be a JSON array of raw findings from your scanner (e.g., Semgrep, CodeQL, Checkmarx). [CODE_CONTEXT_SNIPPETS] should include the relevant source files or diff hunks that surround each finding. [APPLICATION_PROFILE] describes the application's runtime environment, exposure, and data classification. [TRIAGE_RULES] encodes your organization's severity definitions, escalation criteria, and acceptable risk thresholds. After the model returns a response, validate the JSON structure against the schema before ingesting it into your vulnerability management system. For high-risk findings, always require human review before closing or deferring.
Prompt Variables
Required inputs for the SAST Finding Severity Triage prompt. Each placeholder must be populated before the prompt is assembled and sent. Missing or malformed inputs are a leading cause of false negatives and mis-ranked findings.
| Placeholder | Purpose | Example | Validation Notes |
|---|---|---|---|
[SAST_FINDINGS_JSON] | Raw static analysis findings in a structured format, including rule IDs, file paths, line numbers, and messages. | {"findings": [{"rule_id": "java/ssrf", "file": "src/api/ProxyService.java", "line": 42, "message": "Untrusted URL flows to HTTP request."}]} | Must be valid JSON. Reject if the array is empty or the schema is missing required fields like rule_id or file. Parse check required. |
[CODE_SNIPPETS] | Full file content or relevant code context for each finding, keyed by file path. Used to assess exploitability and filter false positives. | {"src/api/ProxyService.java": "public class ProxyService { ... }"} | Each key must match a file path in [SAST_FINDINGS_JSON]. Null values are allowed if the file is deleted, but a warning should be logged. String length > 0 check. |
[APPLICATION_PROFILE] | A description of the application's architecture, data sensitivity, and exposure. Used to determine business impact. | {"type": "external_api", "data_classification": "pii", "auth_mechanism": "oauth2", "internet_facing": true} | Must be valid JSON. The 'type' and 'data_classification' fields are required. Use a schema check to ensure no unknown values are passed. |
[DEPENDENCY_MANIFEST] | The project's dependency manifest (e.g., package.json, pom.xml) to check if a vulnerable library is the root cause. | {"dependencies": {"express": "4.17.1", "lodash": "4.17.21"}} | Optional. If null, the prompt should not attempt dependency analysis. If provided, it must be valid JSON. Null allowed. |
[FALSE_POSITIVE_PATTERNS] | A list of known false positive signatures specific to the organization, such as test file paths or safe wrapper functions. | ["src/test/", "/mock/", "Sanitizer.sanitizeUrl"] | Must be a valid JSON array of strings. An empty array is allowed. Each string is treated as a substring match against file paths and code snippets. |
[SEVERITY_TAXONOMY] | The organization's custom severity levels and criteria, overriding the default CVSS-based ranking. | {"levels": [{"name": "BLOCKER", "condition": "Exploitable with high business impact and no mitigating controls."}]} | Optional. If null, a default taxonomy is used. If provided, it must be a valid JSON object with a 'levels' array. Null allowed. |
[OUTPUT_SCHEMA] | The exact JSON schema the model must use for its response, including required fields for each triaged finding. | {"type": "object", "properties": {"triaged_findings": {"type": "array", "items": {"$ref": "#/definitions/finding"}}}, "required": ["triaged_findings"]} | Must be a valid JSON Schema (draft-07 or later). Reject the prompt assembly if the schema fails to parse. This is the contract for downstream processing. |
Implementation Harness Notes
How to wire the SAST severity triage prompt into a CI/CD pipeline or security workflow with validation, retries, and human review gates.
Integrating the SAST Finding Severity Triage prompt into a production pipeline requires treating it as a deterministic step in a vulnerability management workflow, not a conversational query. The prompt expects a batch of raw SAST findings with associated code snippets, rule metadata, and repository context. Your harness should assemble this payload from your SAST tool's output (e.g., Semgrep JSON, CodeQL SARIF, Checkmarx XML) and normalize it into the [SAST_FINDINGS] structure before calling the model. The harness must also inject [TRIAGE_POLICY]—a string containing your organization's severity definitions, exploitability criteria, and business impact tiers—so the model's ranking aligns with your internal risk appetite rather than generic CVSS assumptions. Without this policy injection, the model will default to textbook severity ratings that may not match your threat model or asset criticality.
The implementation should wrap the model call in a validation and retry layer. After receiving the model's JSON output, validate it against the expected [OUTPUT_SCHEMA] before any downstream action. Check that every finding in the input has a corresponding triage entry, that severity values are within your defined enum, that deduplication groups reference valid finding IDs, and that false-positive classifications include a reasoning string. If validation fails, construct a retry prompt that includes the original input, the malformed output, and a specific error message describing the schema violation. Limit retries to a maximum of 2 attempts before flagging the batch for human review. Log every attempt—input hash, model response, validation errors, and retry count—so you can diagnose whether failures stem from prompt ambiguity, model inconsistency, or edge-case input shapes. For high-risk repositories (e.g., payment systems, auth services), add a mandatory human approval gate after successful validation: route findings classified as CRITICAL or HIGH to a security engineer's review queue before they appear in the developer's backlog.
Model choice matters for this workflow. Use a model with strong reasoning capabilities and a large context window, as a single batch may contain dozens of findings with code context. If your SAST output is large, implement a pre-processing splitter that groups findings by file or rule category and processes batches of no more than 15-20 findings per call to stay within reliable attention limits. For cost and latency optimization, cache the [TRIAGE_POLICY] and [OUTPUT_SCHEMA] as a reusable system prompt prefix. If you have a labeled dataset of manually triaged findings, run this prompt against it before deployment and measure agreement on severity classification, false-positive detection, and deduplication grouping. Set a minimum agreement threshold (e.g., 85% on severity, 90% on false-positive recall) as a release gate. When the model's output disagrees with ground truth, log those cases as eval failures for prompt iteration. Do not deploy this prompt without first establishing a baseline accuracy measurement against your own historical triage data.
Expected Output Contract
Defines the exact fields, types, and validation rules for the SAST triage response. Use this contract to build a parser, validator, or retry gate before the output enters any downstream workflow.
| Field or Element | Type or Format | Required | Validation Rule |
|---|---|---|---|
triage_id | string (UUID v4) | Must parse as a valid UUID v4. Reject if missing or malformed. | |
original_finding_ref | string | Must match a finding ID from the input [SAST_FINDINGS] array. Reject if unmatched. | |
deduplication_group | string or null | If not null, must match the triage_id of another finding in the same batch. Null allowed only when no duplicate exists. | |
false_positive_classification | enum: TRUE_POSITIVE | LIKELY_FALSE_POSITIVE | FALSE_POSITIVE | Must be one of the three enum values. If LIKELY_FALSE_POSITIVE, the false_positive_reasoning field must be non-empty. | |
false_positive_reasoning | string or null | Required when false_positive_classification is not TRUE_POSITIVE. Must contain at least one concrete code-path reference. Null allowed only for TRUE_POSITIVE. | |
exploitability_rating | enum: CRITICAL | HIGH | MEDIUM | LOW | NONE | Must be one of the five enum values. If NONE, the finding must be classified as FALSE_POSITIVE or LIKELY_FALSE_POSITIVE. | |
business_impact_rating | enum: CRITICAL | HIGH | MEDIUM | LOW | NONE | Must be one of the five enum values. Cannot be CRITICAL unless exploitability_rating is also CRITICAL or HIGH. | |
composite_severity | enum: CRITICAL | HIGH | MEDIUM | LOW | INFO | Must be derived from exploitability_rating and business_impact_rating. Reject if the combination violates the defined severity matrix in [SEVERITY_MATRIX]. |
Common Failure Modes
SAST finding severity triage fails when the model hallucinates exploitability, misjudges business context, or treats every finding as critical. These failure modes break trust in automated triage and waste engineering cycles on false escalations.
Severity Inflation Without Exploitability Evidence
What to watch: The model assigns Critical or High severity based on rule names or CWE categories alone, without analyzing whether the vulnerable code path is actually reachable or exploitable in the deployed context. This produces alarm fatigue and desensitizes teams to real issues. Guardrail: Require the prompt to output a separate exploitability_assessment field that cites specific code evidence (e.g., 'user input reaches this sink without sanitization at line X') before accepting any severity above Medium. Add a validator that rejects findings where severity is High but exploitability evidence is missing or generic.
False Negative Suppression of Chained Vulnerabilities
What to watch: The model correctly identifies individual low-severity findings but fails to recognize that two or more findings chained together create a high-impact attack path. A missing auth check combined with an SSRF sink may be individually Medium but collectively Critical. Guardrail: Add a post-triage correlation step in the harness that groups findings by affected component and data flow. Include a secondary prompt that ingests clusters of Medium findings and asks: 'Do any of these findings combine to create a higher-severity attack path? If so, escalate the composite finding.'
Business Impact Misranking from Missing Context
What to watch: The model ranks findings purely on technical severity without understanding which systems handle PII, process payments, or sit in the critical path for revenue. A Medium SQL injection in a public-facing payment service is more urgent than a Critical finding in an internal dev tool. Guardrail: Always inject a [ASSET_CONTEXT] block into the prompt that maps each affected component to a data classification (PII, PCI, Public, Internal) and a business criticality tier. Instruct the model to adjust final severity upward by one tier when the asset context indicates regulated or revenue-critical data.
Deduplication Failures Creating Duplicate Tickets
What to watch: Raw SAST output often contains multiple findings for the same root cause (e.g., the same unsanitized input flowing to five different sinks). The model treats each as independent, producing five tickets for one fix. Guardrail: Add a deduplication pass before severity triage. Use a prompt that groups findings by source_location and vulnerability_class, then outputs a single representative finding with a duplicate_of field. Only the deduplicated set proceeds to severity ranking. Validate that no two output findings share the same root cause signature.
Confidence Overstatement on Ambiguous Findings
What to watch: The model assigns high confidence to findings where the code path is complex, the sanitizer is non-obvious, or the framework provides implicit protection. This leads to false positives that waste developer time on investigation. Guardrail: Require the output schema to include a confidence field with explicit reasoning. Add a prompt instruction: 'If you cannot trace the complete data flow from source to sink, or if a framework-level protection might apply, set confidence to Low and flag for human review.' Implement a routing rule that sends Low-confidence High-severity findings to a human queue rather than auto-escalating.
Stale Baseline Causing Regression Blindness
What to watch: The model triages new findings in isolation without comparing against previously accepted risks or known false positives. A finding that was triaged as 'accepted risk' last week gets re-escalated, creating noise and eroding trust. Guardrail: Include a [BASELINE] section in the prompt containing previously triaged finding signatures (file + rule + sink) and their dispositions. Instruct the model: 'If a new finding matches a baseline entry with disposition Accepted or False Positive, classify it as Baseline Match and suppress it unless the code diff shows the sink is now reachable from a new source.'
Evaluation Rubric
Use this rubric to test the SAST triage prompt against a manually triaged golden dataset before shipping. Each criterion targets a specific failure mode observed in automated severity triage.
| Criterion | Pass Standard | Failure Signal | Test Method |
|---|---|---|---|
Severity Alignment | Output severity matches human-assigned severity for >= 90% of findings in the golden set | Severity mismatch rate exceeds 10%, especially for Medium vs High boundary cases | Run prompt on 100 manually triaged findings; compute exact-match accuracy and weighted kappa |
False Positive Suppression | Prompt correctly identifies >= 85% of known false positives as 'False Positive' or 'Info' severity | Known false positives are assigned Medium or higher severity, or marked as true positives without qualification | Use a subset of 50 confirmed false positives from the golden set; measure precision of suppression |
Critical Finding Recall | 100% of known Critical/High findings in the golden set are assigned High or Critical severity | Any known Critical finding is classified as Medium, Low, or False Positive | Isolate all Critical findings in the golden set; verify no down-severity misclassification |
Deduplication Accuracy | Prompt groups related findings with the same root cause into a single output record with a count >= 1 | Duplicate findings from the same sink and source appear as separate top-level records without cross-reference | Feed a batch containing 5 variants of the same SQL injection; verify output contains exactly 1 primary record |
Reasoning Traceability | Every severity assignment includes a specific code-line or data-flow reference in the [REASONING] field | [REASONING] field contains only generic statements like 'this looks risky' without code evidence | Parse [REASONING] fields; assert each contains at least one file path, line number, or variable name from the input |
Output Schema Compliance | Output is valid JSON matching the [OUTPUT_SCHEMA] with all required fields present and correctly typed | Output is missing required fields, contains extra untyped keys, or uses string where array is expected | Validate output with a JSON Schema validator; reject any response that fails structural validation |
Confidence Calibration | Low-confidence findings (confidence < 0.7) are never assigned Critical severity without an [ESCALATION_FLAG] set to true | A finding with confidence 0.4 is assigned Critical severity with no escalation flag or human-review instruction | Filter outputs where confidence < 0.7 and severity == 'Critical'; assert [ESCALATION_FLAG] is true |
Business Impact Justification | High and Critical findings include a non-empty [BUSINESS_IMPACT] field describing data exposure, system compromise, or compliance risk | [BUSINESS_IMPACT] is null, empty string, or restates the technical finding without business context | Extract [BUSINESS_IMPACT] for all High/Critical outputs; assert length > 50 characters and contains a business consequence term |
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Adapt This Prompt
How to adapt
Use the base prompt with lighter validation. Remove strict output schema requirements and let the model reason in natural language first. Start with a single SAST tool's output format (e.g., Semgrep JSON) rather than a multi-tool union schema. Use a small batch of 5-10 findings to iterate quickly.
Watch for
- Missing schema checks causing downstream parsing failures
- Overly broad severity inflation when the model lacks calibration examples
- Hallucinated CWE mappings when the tool already provides them
- Token exhaustion on large finding sets without chunking

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us