Inferensys

Prompt

Static Analysis Finding Risk Scoring Prompt Template

A practical prompt playbook for security and DevSecOps teams using AI to score and prioritize static analysis findings based on exploitability, reachability, data sensitivity, and business impact.
Risk analyst performing AI risk assessment on laptop, risk matrices visible, casual office risk session.
PROMPT PLAYBOOK

When to Use This Prompt

Define the job, reader, and constraints for scoring static analysis findings.

This prompt is designed for security engineers, DevSecOps practitioners, and platform teams who need to move from a flat list of static analysis results to a prioritized, risk-ranked backlog. The job-to-be-done is consistent, evidence-based triage: given a single finding from a SAST or linting tool, the prompt produces a structured risk score, a priority level, and a clear justification that links exploitability, reachability, data sensitivity, and business impact. The ideal user is someone integrating AI into a security review pipeline where raw tool output is too noisy to act on directly, and where every finding must be scored against a repeatable rubric before it reaches a human reviewer or an automated remediation queue.

Use this prompt when you have a well-defined static analysis finding with enough context to reason about its risk—typically a finding ID, rule identifier, file path, line number, and a description of the vulnerable pattern. The prompt assumes you can supply the surrounding code snippet and, where relevant, deployment context such as whether the affected component faces the internet, handles sensitive data, or sits on a critical path. Do not use this prompt for real-time intrusion detection, dynamic analysis results, or findings from penetration tests where exploitability has already been demonstrated; those workflows require different evidence models and escalation paths. This prompt is also not a replacement for a CVSS calculator or a formal threat model—it is a triage accelerator that produces a defensible, auditable score when human review bandwidth is limited.

Before wiring this into a production pipeline, define your risk tolerance thresholds and calibrate the scoring factors against a set of findings your team has already triaged manually. Run the prompt against those known cases and compare the output to your ground-truth priorities. Expect to tune the factor descriptions in the prompt template to match your organization's specific data classification labels, deployment topology, and regulatory surface. The next section provides the copy-ready template; after that, the implementation harness section covers validation, retries, and human-review gates for high-severity findings.

PRACTICAL GUARDRAILS

Use Case Fit

Where the Static Analysis Finding Risk Scoring Prompt works, where it fails, and what inputs it assumes before you wire it into a triage pipeline.

01

Good Fit: Curated SAST Findings

Use when: findings are already deduplicated and enriched with CWE identifiers, file paths, and reachability data. The prompt adds value by weighting exploitability against business context. Avoid when: raw, noisy linter output is dumped directly—triage and deduplication must happen upstream.

02

Bad Fit: Undefined Business Context

Risk: scoring defaults to generic severity when the model lacks context about data sensitivity or system criticality. Guardrail: always supply a concrete [DATA_CLASSIFICATION] and [SYSTEM_CRITICALITY] input. If these are unknown, route to a human for context gathering before scoring.

03

Required Inputs

Required: [FINDING_DESCRIPTION], [CWE_ID], [FILE_PATH], [REACHABILITY], [DATA_SENSITIVITY], and [BUSINESS_IMPACT]. Optional but recommended: [EXPLOIT_MATURITY] and [PRIOR_FIX_HISTORY]. Missing inputs degrade score reliability and should block automated prioritization.

04

Operational Risk: Score Drift

Risk: inconsistent scoring across similar findings erodes trust in automated triage. Guardrail: implement eval checks that compare scores for findings with identical CWE, reachability, and impact. Flag variance above a defined threshold for human review before the score enters a workflow.

05

Operational Risk: Justification Quality

Risk: a plausible but wrong justification can mislead reviewers into accepting an incorrect priority. Guardrail: require the output to cite specific input factors in its justification. Validate that every justification sentence maps to a supplied input field before the score is surfaced in a dashboard.

06

Pipeline Integration

Use when: the prompt is called after deduplication and before ticket creation. Avoid when: the output feeds directly into an auto-remediation pipeline without human approval for Critical or High scores. Always route Critical findings to a human approval queue regardless of model confidence.

PROMPT PLAYBOOK

Copy-Ready Prompt Template

A reusable prompt with square-bracket placeholders for scoring a single static analysis finding.

This prompt template is the core scoring engine for a single static analysis finding. It expects a structured description of the finding, repository context, and a defined risk taxonomy. The model's job is to produce a consistent, evidence-backed risk score and priority level, not to interpret raw linter output. Use this template when you have already extracted and normalized a finding into the required input fields. Do not use it for batch triage, executive summaries, or fix generation—those are separate playbooks.

text
You are a security-focused static analysis risk scorer. Your task is to evaluate a single static analysis finding and produce a risk score with clear justification.

## INPUT
- Finding: [FINDING_DESCRIPTION]
- File path: [FILE_PATH]
- Line range: [LINE_RANGE]
- Rule ID: [RULE_ID]
- Rule severity from tool: [TOOL_SEVERITY]
- Language: [LANGUAGE]
- Repository context: [REPO_CONTEXT]
- Data sensitivity classification: [DATA_SENSITIVITY]
- Deployment exposure: [DEPLOYMENT_EXPOSURE]

## SCORING DIMENSIONS
Score each dimension from 0 (none) to 4 (critical).
1. Exploitability: How easy is it for an attacker to trigger this finding?
2. Reachability: Is the vulnerable code reachable from an untrusted entry point?
3. Data Sensitivity Impact: What data or resources are at risk if exploited?
4. Business Impact: What is the blast radius in terms of system, user, or revenue impact?

## OUTPUT SCHEMA
Return a JSON object with this exact structure:
{
  "finding_id": "string",
  "dimension_scores": {
    "exploitability": {"score": 0-4, "justification": "string"},
    "reachability": {"score": 0-4, "justification": "string"},
    "data_sensitivity_impact": {"score": 0-4, "justification": "string"},
    "business_impact": {"score": 0-4, "justification": "string"}
  },
  "composite_risk_score": 0.0-10.0,
  "priority_level": "CRITICAL|HIGH|MEDIUM|LOW|INFO",
  "scoring_notes": "string explaining the overall rationale",
  "uncertainty_flags": ["string"]
}

## CONSTRAINTS
- The composite_risk_score is the weighted average: (exploitability * 0.3) + (reachability * 0.3) + (data_sensitivity_impact * 0.2) + (business_impact * 0.2), then scaled to 0-10.
- Priority level thresholds: CRITICAL >= 8.0, HIGH >= 6.0, MEDIUM >= 4.0, LOW >= 2.0, INFO < 2.0.
- Every dimension score must have a concrete justification referencing the finding details or repository context.
- If you lack sufficient information to score a dimension confidently, set the score to 0 and add an uncertainty flag explaining what is missing.
- Do not inflate scores due to the tool's original severity. Re-evaluate independently.
- If the finding is in test code, a build script, or unreachable dead code, reflect that in reachability and exploitability.

To adapt this template, replace the square-bracket placeholders with actual values from your static analysis pipeline. The [REPO_CONTEXT] field should include relevant architectural notes, trust boundaries, and data flow summaries—not the entire codebase. The [DATA_SENSITIVITY] and [DEPLOYMENT_EXPOSURE] fields work best when populated from a pre-defined taxonomy (e.g., PII, PCI, PHI, internal-only, public-facing). If your organization uses different scoring dimensions or weights, adjust the CONSTRAINTS section and the OUTPUT_SCHEMA field names accordingly. Keep the output schema strict so downstream automation can parse scores reliably.

Before deploying, test this prompt against a golden set of 20-30 findings with known risk levels. Compare the model's composite scores and priority levels against your security team's manual assessments. Watch for score inflation on high-severity tool findings and score deflation on findings in test files. If the model consistently misjudges reachability, add a few annotated examples to the prompt showing correct reachability reasoning for your architecture. The next section covers how to wire this prompt into an application harness with validation, retries, and human review gates.

IMPLEMENTATION TABLE

Prompt Variables

Inputs the prompt needs to produce a reliable risk score and justification. Validate each before calling the model.

PlaceholderPurposeExampleValidation Notes

[FINDING_DETAILS]

Raw static analysis finding including rule ID, message, file path, and line number

{"rule_id": "BANDIT_B301", "message": "pickle.load called", "file": "src/cache.py", "line": 42}

Must be a valid JSON object with non-empty rule_id, message, file, and line fields. Reject if file path is absolute and outside the repository root.

[CODE_SNIPPET]

Surrounding source code context for the finding, typically 20-50 lines around the flagged line

def load_cache(path): with open(path, 'rb') as f: return pickle.load(f)

Must be a non-empty string. Validate that the snippet contains the line referenced in [FINDING_DETAILS]. Truncate to 2000 characters if longer.

[REACHABILITY_GRAPH]

Call graph or import chain showing whether the vulnerable code is reachable from an entry point

main() -> handle_request() -> load_cache() -> pickle.load()

Optional. If provided, must be a non-empty string. If null, the prompt should still produce a score but must flag reachability as unknown.

[DATA_CLASSIFICATION]

Sensitivity level of data the code path handles, drawn from a data catalog or manual annotation

PII_HIGH

Must be one of: PUBLIC, INTERNAL, CONFIDENTIAL, PII_LOW, PII_MEDIUM, PII_HIGH, PCI, PHI. Reject unknown values. If null, default to UNKNOWN and require the prompt to note reduced confidence.

[DEPLOYMENT_CONTEXT]

Where the affected code runs: production, staging, CI, or an internal tool

production-public-api

Must be a non-empty string. Recommended values: production-public-api, production-internal, staging, ci-pipeline, local-dev. If null, default to unknown and require the prompt to flag context uncertainty.

[BUSINESS_IMPACT]

Free-text description of the business function the code supports and the impact of compromise

User session cache for authentication tokens. Compromise could allow session hijacking across all active users.

Must be a non-empty string. If null, the prompt must note that business impact was not provided and score may be conservative.

[PRIOR_SCORES]

Previous risk scores for the same finding or similar findings, used for consistency calibration

[{"finding_id": "SEC-142", "score": 8.2, "date": "2025-03-15"}]

Optional. If provided, must be a JSON array of objects with finding_id, score, and date fields. Score must be a float between 0 and 10. Reject malformed entries.

PROMPT PLAYBOOK

Implementation Harness Notes

How to wire the risk scoring prompt into a SAST triage pipeline with validation, retry, and human review.

This prompt is designed to be one step in a larger static analysis triage pipeline, not a standalone chatbot interaction. The typical integration point is after a SAST tool (Semgrep, CodeQL, Fortify, etc.) has produced findings and before those findings are routed to developer queues or security review boards. The harness should call the model with one finding at a time to keep context focused and token costs predictable. Batching multiple findings in a single call risks score leakage between unrelated issues and makes per-finding validation harder.

The implementation harness must enforce a strict output contract. After receiving the model response, validate that the JSON contains all required fields (risk_score, priority_level, factor_breakdown, justification_summary), that risk_score is an integer between 1 and 10, and that priority_level is one of the allowed enum values (CRITICAL, HIGH, MEDIUM, LOW, INFO). If validation fails, retry once with the same prompt plus the validation error message appended as a [CORRECTION] block. If the retry also fails, route the finding to a human review queue with the raw model output and validation errors attached. Log every attempt—including the prompt version, model, input finding ID, output, validation result, and retry count—to your observability platform for later prompt debugging and regression analysis.

For high-risk repositories (auth services, payment systems, PII handlers), add a mandatory human approval gate for any finding scored HIGH or CRITICAL before the finding enters a developer's backlog. The harness should also compare the model's score against any existing scanner severity (e.g., CodeQL's error vs warning) and flag discrepancies greater than two severity levels for review—this catches cases where the model's risk reasoning diverges significantly from the static analysis tool's built-in assessment. Model choice matters here: prefer a model with strong reasoning capabilities (GPT-4o, Claude 3.5 Sonnet) over smaller or faster models, because the scoring task requires multi-factor reasoning about exploitability, reachability, and business impact that smaller models tend to flatten into generic medium scores. If latency is critical, consider running the prompt asynchronously after finding ingestion rather than blocking the triage pipeline.

IMPLEMENTATION TABLE

Expected Output Contract

Schema contract for the risk scoring response. Every field must be present and pass the validation rule before the output is accepted by downstream systems.

Field or ElementType or FormatRequiredValidation Rule

finding_id

string

Must match the [FINDING_ID] input exactly; no truncation or modification

risk_score

number (0.0-10.0)

Must be a float between 0.0 and 10.0 inclusive; one decimal place precision

priority_level

enum: CRITICAL | HIGH | MEDIUM | LOW | INFO

Must be one of the five allowed enum values; case-sensitive

exploitability_score

number (0.0-10.0)

Must be a float between 0.0 and 10.0 inclusive; must not exceed risk_score when reachability is LOW

reachability_assessment

enum: REACHABLE | CONDITIONALLY_REACHABLE | UNREACHABLE | UNKNOWN

Must be one of the four allowed enum values; UNKNOWN requires explicit justification in justification_summary

data_sensitivity_impact

enum: PII | PCI | PHI | CREDENTIALS | INTERNAL | PUBLIC | NONE

Must be one of the seven allowed enum values; PII, PCI, PHI, or CREDENTIALS must force priority_level to CRITICAL or HIGH

business_impact_rationale

string

Must be 30-300 characters; must reference at least one concrete business context from [BUSINESS_CONTEXT] input

justification_summary

string

Must be 50-500 characters; must explicitly mention exploitability, reachability, and data sensitivity factors used in scoring

confidence_level

number (0.0-1.0)

Must be a float between 0.0 and 1.0 inclusive; values below 0.6 must trigger human review flag in calling system

human_review_recommended

boolean

Must be true if confidence_level < 0.6 or reachability_assessment is UNKNOWN; otherwise may be true or false

scoring_factors

array of strings

Must contain 2-5 strings; each string must map to a named factor from the [SCORING_RUBRIC] input; no duplicate factors allowed

PRACTICAL GUARDRAILS

Common Failure Modes

What breaks first when scoring static analysis findings and how to guard against it.

01

Over-Scoring Low-Impact Findings

What to watch: The model inflates severity when it sees security keywords (e.g., 'SQL injection', 'hardcoded credentials') without assessing actual exploitability or reachability. A finding in a test fixture or dead code path gets scored as critical. Guardrail: Require the prompt to explicitly check reachability and deployment context before assigning severity. Add a 'Reachability Assessment' field to the output schema and validate that unreachable code is capped at Low severity regardless of CWE category.

02

Inconsistent Scoring Across Similar Findings

What to watch: Two findings with the same CWE, same file type, and same data sensitivity receive different risk scores because the model's justification drifts between invocations. This erodes trust in automated triage. Guardrail: Include a calibration example in the prompt showing two similar findings with identical scores. Add an eval check that compares scores for findings with matching CWE, reachability, and data sensitivity, flagging any variance greater than one severity level.

03

Missing Factor Justification

What to watch: The model produces a risk score and priority level but skips the required justification for each factor (exploitability, reachability, data sensitivity, business impact). The output looks complete but is unauditable. Guardrail: Use a strict output schema that requires a non-empty justification string for each factor. Add a post-generation validation step that rejects outputs where any justification field is empty, fewer than 20 characters, or contains only generic phrases like 'this is a risk.'

04

Context Window Truncation on Large Finding Lists

What to watch: When scoring a batch of findings, the model loses fidelity on later items as the context window fills. Scores become more uniform and justifications get shorter, masking real risk variance. Guardrail: Limit batch size to 5-7 findings per request. If processing a larger set, sort findings by preliminary severity first so the highest-risk items are scored with full context. Log justification length per finding position to detect truncation drift.

05

CWE Misclassification Cascading into Wrong Score

What to watch: The model accepts a tool-reported CWE without verification, then applies the wrong risk model. A finding tagged as CWE-79 (XSS) that is actually CWE-352 (CSRF) gets scored against the wrong exploitability and impact profile. Guardrail: Add a 'CWE Verification' step in the prompt that asks the model to confirm the CWE matches the finding description before scoring. If the description and CWE conflict, flag the finding for human review rather than scoring it with low confidence.

06

Business Impact Hallucination

What to watch: The model invents business context when none is provided—assuming the affected service handles payments, PII, or critical infrastructure without evidence. This produces high-impact scores for systems the model knows nothing about. Guardrail: Require the prompt to use only explicitly provided business context. If no business impact context is supplied, default to 'Unknown' and cap the business impact factor at Medium. Add an eval that checks whether the justification references only provided context fields.

IMPLEMENTATION TABLE

Evaluation Rubric

Use this rubric to evaluate the quality and consistency of risk scores generated by the Static Analysis Finding Risk Scoring prompt before deploying it to production. Each criterion targets a specific failure mode common in automated risk assessment.

CriterionPass StandardFailure SignalTest Method

Score Justification

Every risk score is accompanied by a non-empty justification string that references specific evidence from the [FINDING_DETAILS] and [REPOSITORY_CONTEXT] inputs.

Missing justification, generic justification like 'high risk', or justification that repeats the score without citing evidence.

Parse the output. Assert justification field is a non-empty string. Use a substring check to confirm it contains at least one keyword from the provided inputs.

Factor Consistency

The final risk score logically aligns with the individual factor scores for Exploitability, Reachability, Data Sensitivity, and Business Impact. A high final score with all low factors is a failure.

Final score is 'CRITICAL' but all factor scores are 'LOW'. Final score is 'LOW' but multiple factors are 'CRITICAL'.

Use a rule-based validator. Calculate an expected score range from the factor scores. Flag any output where the final score deviates from this range by more than one level.

Schema Adherence

The output is valid JSON that strictly matches the defined [OUTPUT_SCHEMA], including all required fields and correct enum values for scores.

Output is not valid JSON. Required fields like finding_id or risk_score are missing. Enum values like 'HIGH' are misspelled or use an undefined level.

Validate the output against the JSON schema programmatically. Check for missing required fields and invalid enum values. A single schema violation is a failure.

Input Grounding

The finding_id in the output exactly matches the id field from the [FINDING_DETAILS] input. The output does not introduce hallucinated file paths or function names not present in the input.

The output finding_id is null or does not match the input. The justification mentions a code element not found in the provided context.

Perform an exact string match on finding_id. For grounding, extract all code symbols from the justification and verify each is present in the [FINDING_DETAILS] or [REPOSITORY_CONTEXT] inputs.

Scoring Calibration

Across a test set of 20 findings with known risk levels, the model's score agrees with the expert-provided label at least 85% of the time, with no more than one level of disagreement.

Agreement rate falls below 85%. A finding labeled 'LOW' by the expert is scored 'CRITICAL' by the model, indicating a severe miscalibration.

Run the prompt on a golden dataset of 20 pre-labeled findings. Calculate the exact match accuracy and the mean absolute error on a numeric scale. Review all off-by-two-level errors manually.

Uncertainty Handling

When input data is insufficient to determine a factor score (e.g., Data Sensitivity is unknown), the output explicitly flags this with a confidence note or a default 'INFO' score, rather than guessing.

A factor score is confidently set to 'HIGH' with no evidence in the input. The output lacks any confidence or uncertainty notes when key data is missing.

Include findings with deliberately missing fields in your test set. Assert that the output's confidence_notes field is populated and that the corresponding factor score is not set to a definitive level like 'HIGH' or 'CRITICAL'.

Priority Level Logic

The priority_level field is correctly derived from the risk_score and the effort_estimate fields, following the documented mapping in the prompt's [CONSTRAINTS].

A 'CRITICAL' risk finding with a 'LOW' effort estimate is assigned a 'P4' priority. A 'LOW' risk finding is assigned a 'P1' priority.

Implement a post-processing check that applies the priority mapping rules from the prompt. Assert that the output's priority_level matches the result of this deterministic mapping function.

ADAPTATION OPTIONS

Adapt This Prompt

How to adapt

Use the base prompt with a single SAST tool and a simplified risk model. Replace [TOOL_NAME] with your scanner (e.g., Semgrep, CodeQL) and [RISK_FRAMEWORK] with a basic 3-tier scale (Low/Medium/High). Drop the [EVIDENCE_REQUIREMENTS] section and accept free-text justification.

Watch for

  • Inconsistent severity mapping across findings
  • Missing exploitability reasoning when the model skips optional sections
  • Overly broad justifications that don't reference specific code paths
Prasad Kumkar

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.