Summary
Add an opt-in AI-powered executive summary layer to SecuScan's report generation pipeline. After a scan completes, an LLM summarizes the findings into a concise, human-readable paragraph that gets embedded into HTML and PDF reports.
Problem
backend/secuscan/reporting.py currently generates HTML, PDF, and SARIF reports by concatenating raw scan findings with no intelligence layer. Users — especially non-technical stakeholders — receive a wall of raw vulnerability data with no context, prioritization narrative, or recommended next steps.
There is currently no way to get a quick "what happened in this scan and what matters most?" answer from a report without reading every finding manually.
Proposed Solution
Add a backend/secuscan/ai_summary.py module that accepts structured scan findings, builds a prompt, calls an LLM (OpenAI-compatible API), and returns a short executive summary string.
Hook this into ReportGenerator so the summary is injected as a section at the top of HTML and PDF reports. The feature must be opt-in — if no API key is configured, report generation continues exactly as before with no breakage.
Suggested approach
-
New module: backend/secuscan/ai_summary.py
generate_summary(findings: list[dict], model: str) -> str
- Builds a structured prompt from finding count, severity distribution, and
top critical/high findings
- Calls an OpenAI-compatible endpoint (supports OpenAI, Ollama, any local LLM)
- Returns a 3–5 sentence plain-English summary
-
Config: add AI_SUMMARY_ENABLED, AI_SUMMARY_API_KEY, AI_SUMMARY_BASE_URL,
AI_SUMMARY_MODEL to backend/secuscan/config.py (all optional, default off)
-
reporting.py changes:
generate_html_report — inject summary block near top of report if enabled
_generate_pdf_html_report — same for PDF output
- SARIF output untouched (SARIF is a machine format)
-
Frontend (optional stretch): surface ai_summary field from the scan result
API in the Task Details panel
Acceptance Criteria
Suggested Files
backend/secuscan/ai_summary.py — new module (primary work)
backend/secuscan/config.py — add 4 new optional env vars
backend/secuscan/reporting.py — inject summary into HTML/PDF generation
backend/requirements.txt — add openai>=1.0.0
testing/backend/unit/test_ai_summary.py — unit tests with mocked LLM calls
docs/AI_SUMMARY.md — setup and usage guide
Test Plan
- Unit test
generate_summary() with a mocked openai.ChatCompletion response
- Unit test that report generation proceeds normally when feature is disabled
- Unit test prompt structure: verify finding count, severities, and top findings
appear in the constructed prompt
- Manually enable the feature with an OpenAI key or local Ollama instance and
verify the summary section renders correctly in HTML and PDF output
- Confirm existing backend test suite (
./testing/test_python.sh) passes with
no regressions
Additional Notes
- Use
openai Python client with configurable base_url so contributors can
test locally with Ollama (http://localhost:11434/v1) without needing a paid
API key
- Summary prompt should never send raw target hostnames or credentials — only
finding metadata (severity, category, count)
- This is additive only. Zero breaking changes to existing report output.
- Suggested default model:
gpt-4o-mini (cheap, fast) or llama3 for local use
Summary
Add an opt-in AI-powered executive summary layer to SecuScan's report generation pipeline. After a scan completes, an LLM summarizes the findings into a concise, human-readable paragraph that gets embedded into HTML and PDF reports.
Problem
backend/secuscan/reporting.pycurrently generates HTML, PDF, and SARIF reports by concatenating raw scan findings with no intelligence layer. Users — especially non-technical stakeholders — receive a wall of raw vulnerability data with no context, prioritization narrative, or recommended next steps.There is currently no way to get a quick "what happened in this scan and what matters most?" answer from a report without reading every finding manually.
Proposed Solution
Add a
backend/secuscan/ai_summary.pymodule that accepts structured scan findings, builds a prompt, calls an LLM (OpenAI-compatible API), and returns a short executive summary string.Hook this into
ReportGeneratorso the summary is injected as a section at the top of HTML and PDF reports. The feature must be opt-in — if no API key is configured, report generation continues exactly as before with no breakage.Suggested approach
New module:
backend/secuscan/ai_summary.pygenerate_summary(findings: list[dict], model: str) -> strtop critical/high findings
Config: add
AI_SUMMARY_ENABLED,AI_SUMMARY_API_KEY,AI_SUMMARY_BASE_URL,AI_SUMMARY_MODELtobackend/secuscan/config.py(all optional, default off)reporting.pychanges:generate_html_report— inject summary block near top of report if enabled_generate_pdf_html_report— same for PDF outputFrontend (optional stretch): surface
ai_summaryfield from the scan resultAPI in the Task Details panel
Acceptance Criteria
ai_summary.pymodule exists withgenerate_summary()functionAI_SUMMARY_ENABLED=falseor API key is absent — no exceptions, no behavior change to existing reports
skip when disabled, prompt construction from findings
openaiadded tobackend/requirements.txt(used for OpenAI-compatibleclient only, works with local models too via
base_url)docs/updated with setup instructions for the AI summary featureSuggested Files
backend/secuscan/ai_summary.py— new module (primary work)backend/secuscan/config.py— add 4 new optional env varsbackend/secuscan/reporting.py— inject summary into HTML/PDF generationbackend/requirements.txt— addopenai>=1.0.0testing/backend/unit/test_ai_summary.py— unit tests with mocked LLM callsdocs/AI_SUMMARY.md— setup and usage guideTest Plan
generate_summary()with a mockedopenai.ChatCompletionresponseappear in the constructed prompt
verify the summary section renders correctly in HTML and PDF output
./testing/test_python.sh) passes withno regressions
Additional Notes
openaiPython client with configurablebase_urlso contributors cantest locally with Ollama (
http://localhost:11434/v1) without needing a paidAPI key
finding metadata (severity, category, count)
gpt-4o-mini(cheap, fast) orllama3for local use