August 4, 2026
Building an AI-Powered Container Scan Analyzer into our CI/CD Pipeline
How we plugged N8N into our ECR orb to turn raw vulnerability reports into developer-ready remediation guides — automatically.

By Bitan Mallick
7 min read
The Problem Nobody Talks About
Every platform team eventually gets security scanning working. You wire up the scanner, it runs on every build, and — great — now you have a pipeline that fails with a wall of CVEs. You've solved visibility. You haven't solved anything else.
The real problem isn't finding vulnerabilities. It's what happens next.
A developer opens the failed build, sees something like:
CVE-2024–45490 critical libexpat 2.5.0
CVE-2023–52425 high libexpat 2.5.0
CVE-2024–3596 critical freeradius-client 1.1.7CVE-2024–45490 critical libexpat 2.5.0
CVE-2023–52425 high libexpat 2.5.0
CVE-2024–3596 critical freeradius-client 1.1.7And then what? Sure, AWS Inspector suggests fixes, but you still need to parse them, cross-reference which ones apply to your Dockerfile, verify the base image ships the update, check if upgrading breaks anything, reconcile conflicting recommendations, and — if you're lucky — arrive at an actionable version pin and Dockerfile diff forty-five minutes later. For each CVE. For every team.
That's the tax we were silently paying on every vulnerable image. We built a tool to close the gap.
Our Setup: The ECR Orb
Before diving into the AI layer, some context. We maintain a CircleCI orb — syngenta-digital/aws-ecr — that handles the full image lifecycle for all our services: build, lint, scan, promote. Amazon Inspector (via inspector-sbomgen) is our scanner. Every image that goes through the build-and-push job gets scanned before it ever touches ECR.
The orb already had:
- Hadolint for Dockerfile linting
- Amazon Inspector for vulnerability scanning
- Compliance checks against our internal security controls service
- Golden Base Image (GBI) management — a curated catalog of org-approved base images
What it didn't have was any intelligence about what to do with scan results.
You can refer more details on our ECR setup and the orb in this article.
The Solution: AI Scan Analysis
We built ai_scan_analysis — a new step in the orb's build-and-push job that fires automatically when critical or high vulnerabilities are detected. It takes the raw Inspector JSON, project's Dockerfile, and our Golden Base Image catalog, ships it all to an N8N workflow, and gets back a complete remediation report as a CircleCI artifact.
One flag enables it all:
- aws-ecr/build-and-push:
context: project_cicd_context
repo: my-service
application_name: my-service
region: us-east-1
enable_n8n_ai_scan_analysis: "true" #ENABLES AI SCAN ANALYSIS- aws-ecr/build-and-push:
context: project_cicd_context
repo: my-service
application_name: my-service
region: us-east-1
enable_n8n_ai_scan_analysis: "true" #ENABLES AI SCAN ANALYSISNo code changes in the application. No extra pipeline steps. No manual triage.
Architecture: How It All Fits Together
The system is built across two layers — the CircleCI pipeline and the N8N workflow — with Claude Sonnet 4 doing the heavy lifting in between.
CircleCI Pipeline
- Docker image is built and scanned using Amazon Inspector
- If critical/high CVEs are found, ai_scan_analysis.sh (in the orb) fires automatically in a non-blocking subshell
- Scan report, Dockerfile, and metadata are base64-encoded and POSTed to the N8N webhook
- The final HTML report lands as a CircleCI artifact (scan_analysis.html)
N8N Workflow
- Receives the payload and fans out in parallel: extracts the Dockerfile, parses vulnerabilities, and fetches the org's Golden Base Image catalog from our internal DevOps Service API
- Filters CVEs down to critical/high only, trims them to essential fields (CVE ID, package, severity, fixed version), and merges all three data streams before passing to the AI
- Claude Sonnet 4 (AWS Bedrock, EU region, via Portkey gateway) receives the structured context and returns a remediation report as HTML
- The response is base64-encoded and returned to the pipeline
Output
- The shell script decodes the response, wraps it in a styled HTML shell with a dark/light theme toggle, and stores it as scan_analysis.html in the CircleCI artifacts directory
**The Shell Script: **ai_scan_analysis.sh
The script (within the CircleCi orb) runs in a non-blocking Bash subshell after the Inspector scan completes — it can never fail the build on its own. A few design choices worth calling out:
- Severity-matched filtering — It only sends CVEs at the severity level you're already failing on. If scan_fail_on_high is enabled, you get analysis on both critical and high. If not, critical only. No noise.
- Payload safety — The Dockerfile and scan report are base64-encoded before transport. The API key is resolved at runtime from a named environment variable and passed as a request header — never embedded in the payload.
- Graceful degradation — If the scan report doesn't exist, no CVEs are found at the target severity, or the N8N call fails for any reason, the script exits 0 and logs a warning. The pipeline is never blocked by the analysis layer.
The N8N Workflow: Inside the AI Engine
N8N orchestrates the entire AI processing pipeline. The workflow has two intake paths — direct payload (scan data embedded in the POST body) and artifact fetch mode (the workflow downloads the scan report from CircleCI artifacts using the build number) — and converges into a single AI call.
- Webhook — Entry point. Accepts POST /ai-scan-analysis with header authentication. The workflow supports both direct payload mode (scan data in the request body) and artifact fetch mode (downloads from CircleCI artifacts using the build number).
- Download Scan Report (conditional) — If scan report is absent from the body, the workflow hits the CircleCI v2 API using the build number to fetch the scan report artifact directly. This handles cases where payload size would exceed webhook limits.
- Get Dockerfile — Extracts the base64-encoded Dockerfile from the request body.
- Get Golden Base Images — Queries our internal DevOps Service API to fetch the curated list of approved base images. The AI uses this to recommend GBI-aligned alternatives rather than arbitrary upstream images.
- Parse Vulnerabilities — A code node that filters to critical/high only and trims each entry to essential fields (severity, CVE ID, package, truncated description, fixed version). This keeps the prompt tight.
- Merge + Aggregate — Combines the three data streams (vulnerabilities, Dockerfile, GBI list) and validates that all three are present and non-empty before proceeding.
- AI Analyzer — The core node. Runs Claude Sonnet 4 on AWS Bedrock via Portkey as an AI gateway.
- Success Response — Returns the AI output as base64 encoded plain text with a 200 status. The shell script on the CircleCI side decodes it and assembles the final report.
**The Output: **scan_analysis.html
The generated report is a self-contained HTML file available under the Artifacts tab in CircleCI. It contains:
- Vulnerability Summary — A table of every CVE analyzed, with current and fixed versions
- Root Cause Analysis — Why each package is vulnerable and what introduced it
- Remediation Steps — Broken into three sections:
- Package-level version pins
- Updated Dockerfile (with Golden Base Image recommendations where applicable)
- Dependency file changes (requirements.txt, package.json, build.gradle, etc.)
- Alternative Mitigations — When a direct fix isn't available
- Dark/Light Theme Toggle — Because developer experience matters
Here's a representative snippet of what the AI generates:
Why This Approach Works
- Non-Blocking Execution
The analysis runs in a Bash subshell. If N8N is unavailable, if the AI call times out, or if anything else goes wrong, the pipeline continues. The scan still fails on critical CVEs (if configured) the analysis is additive, never a blocker.
- Context-Aware, Not Generic
Most LLM-based security tools give you generic CVE advice — the same boilerplate you'd find on NVD. Our implementation sends:
-
The actual Dockerfile — The AI sees your specific base image, your multi-stage build, your package installs
-
The filtered scan results — Not the entire SBOM, just the actionable severity tier
-
Org's Golden Base Images — The AI recommends our approved images, not arbitrary DockerHub tags
The output is specific to the image, stack, and organization's approved catalog.
- Severity-Scoped Analysis
The analysis scope is tied to your fail condition. If scan_fail_on_high: true, you get analysis on high and critical. If not, only critical. This means the report covers exactly the CVEs that are blocking your build — no noise from medium/low findings that aren't blocking anything.
- Cost-Conscious Design
The Parse Vulnerabilities code node intentionally truncates CVE descriptions to 200 characters and strips non-essential SBOM fields before the AI call. Sending a 5MB SBOM to a language model is both expensive and counterproductive — the AI performs better with clean, focused input.
Caveats and Honest Limitations
- AI Recommendations Require Human Judgment
The generated steps are a starting point, not a merge request. Version pins suggested by the AI need to be tested. Base image upgrades might introduce breaking changes. Treat the report as an expert first draft, not a finished solution.
- Latency
The analysis is non-blocking but not instantaneous. An N8N workflow involving an AWS Bedrock call adds 15–60 seconds to the build. The artifact won't appear until the step completes. For large vulnerability sets, this can stretch longer.
- No Feedback Loop (Yet)
The current system doesn't track whether recommendations were acted upon. There's no mechanism to close the loop — to learn which suggestions were useful, which were irrelevant, or to improve prompt quality over time. That's on the roadmap.
- Rate Limits and Availability
N8N webhook availability and Bedrock quota limits are external dependencies. If either is degraded, the step silently skips analysis (exit 0). This is the right failure mode for CI but means teams need to check the Artifacts tab proactively when a scan fails — absence of the artifact doesn't mean no vulnerabilities, it may mean the analysis was skipped.
What This Changed for Our Teams
Before this, a failed scan on a critical CVE meant: find the CVE, figure out which package, check if a fix exists, update the Dockerfile, rebuild, re-scan. An hour of work per incident, often more for multi-CVE failures, and often done reactively rather than proactively.
After: open the Artifacts tab, read the HTML report, copy the Dockerfile snippet, push. The same knowledge work is done — it's just done by the AI on every build rather than by a developer on every failed build.
The secondary benefit is consistency. Different engineers attacking the same CVE would previously arrive at different solutions depending on their familiarity with the vulnerability and the package ecosystem. Now the baseline recommendation is the same for everyone — and it's aligned with our Golden Base Image catalog.
What's Next
A few things we're thinking about:
- Slack/Teams notification — Post a summary of the AI report directly to the team's security channel when a scan fails
- Auto-PR generation — Use the Dockerfile diff from the AI report to open a draft PR with the suggested changes
- Feedback loop — Allow developers to mark recommendations as applied or rejected and feed that signal back to improve prompt quality
- Cost dashboard — Track Bedrock token usage per team/repo to understand the cost-per-analysis and optimize accordingly
Conclusion
Container security scanning is table stakes. Turning scan results into developer action is the hard part — and it's been a largely manual, time-consuming process for most teams.
By connecting Amazon Inspector, N8N, AWS Bedrock, and Claude Sonnet into our existing ECR orb, we automated the gap between vulnerability found and here's exactly how to fix it. The integration is non-breaking, opt-in, and adds no mandatory latency to builds. Teams that enable it get a free expert consultation on every failed scan.
If you found this useful or have questions about the implementation, feel free to reach out. We're always interested in how other teams are approaching security automation in their pipelines.