The Agentic Security Scanning Pipeline
Security vulnerabilities in dependencies are a major risk: a vulnerable package can be exploited by attackers to compromise your app. But manually scanning for vulnerabilities is tedious: you need to run npm audit (or similar), review the findings, determine which are critical, and update the affected packages. What you need is an agentic security scanning pipeline that scans for vulnerabilities automatically, prioritizes them by severity, and auto-fixes the critical ones. With the Deployxa MCP server and an LLM, this is straightforward to build. Here is how.
The direct answer is that a security scanning pipeline is a script that runs on a schedule (e.g., daily), scans your app's dependencies for known vulnerabilities (via npm audit or a tool like Snyk), prioritizes the findings by severity (critical, high, medium, low), and auto-fixes the critical vulnerabilities by updating the affected packages. The pipeline uses an LLM to analyze the findings and recommend fixes, and the Deployxa MCP server to deploy the fixes. For more on security, see our article on the secrets management gap.
Why Manual Security Scanning Does Not Scale
Three problems make manual security scanning unsustainable. First, new vulnerabilities are discovered daily. A package that was safe yesterday might have a critical vulnerability today, which means you need to scan daily. Second, the findings are overwhelming. A typical app has dozens of dependencies, and npm audit can produce hundreds of findings, which makes it hard to identify the critical ones. Third, fixing vulnerabilities requires expertise. Updating a package might break the app (if the new version has breaking changes), which means you need to test each update. An agentic pipeline solves all three problems: it scans daily, prioritizes by severity, and auto-fixes the critical ones (with testing). For more on agentic patterns, see our article on building an AI agent that manages SSL certificates.
What the Security Scanning Pipeline Does
The agentic security scanning pipeline performs the following tasks:
- Scan dependencies. The pipeline runs npm audit (or a tool like Snyk) to scan the app's dependencies for known vulnerabilities.
- Prioritize findings. The pipeline prioritizes the findings by severity (critical, high, medium, low), focusing on critical and high vulnerabilities first.
- Analyze with an LLM. The pipeline uses an LLM to analyze each critical/high vulnerability and recommend a fix (e.g., "update package X to version Y", "replace package X with alternative Y").
- Apply fixes. The pipeline applies the recommended fixes (e.g., updates the package, creates a pull request).
- Verify. The pipeline runs the app's tests to verify the fix did not break anything, and deploys the fix (via the Deployxa MCP server).
- Report. The pipeline sends a Slack notification with the scan results, including the vulnerabilities found, the fixes applied, and any remaining issues.
Step-by-Step: Building the Security Scanning Pipeline
Here is how to build the security scanning pipeline in Python, using an LLM and the Deployxa MCP server.
Step 1: Install dependencies
pip install openai requests schedule
npm install -g @deployxa/mcp-server
deployxa-mcp loginStep 2: Create the pipeline script
# security_scanner.py
import openai
import subprocess
import requests
import schedule
import time
import json
from datetime import datetime
SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/..."
DEPLOYXA_MCP_URL = "http://localhost:3000/mcp"
SCAN_INTERVAL_HOURS = 24
APP_ID = "123"
REPO_PATH = "/path/to/repo"
def call_deployxa(tool, params):
response = requests.post(DEPLOYXA_MCP_URL, json={"tool": tool, "params": params})
return response.json()
def send_slack_notification(message, is_alert=False):
emoji = "🛡️" if not is_alert else "🚨"
requests.post(SLACK_WEBHOOK_URL, json={"text": f"{emoji} {message}"})
def scan_dependencies():
"""Scan dependencies for vulnerabilities using npm audit."""
result = subprocess.run(
["npm", "audit", "--json"],
capture_output=True,
text=True,
cwd=REPO_PATH,
)
if result.returncode != 0 and result.stdout:
try:
return json.loads(result.stdout)
except json.JSONDecodeError:
return {"vulnerabilities": {}}
return json.loads(result.stdout) if result.stdout else {"vulnerabilities": {}}
def analyze_with_llm(vulnerabilities):
"""Use an LLM to analyze vulnerabilities and recommend fixes."""
client = openai.OpenAI()
# Get critical and high vulnerabilities
critical_vulns = []
for name, vuln in vulnerabilities.get("vulnerabilities", {}).items():
if vuln.get("severity") in ["critical", "high"]:
critical_vulns.append({
"package": name,
"severity": vuln.get("severity"),
"via": vuln.get("via", []),
"fixAvailable": vuln.get("fixAvailable", False),
})
if not critical_vulns:
return {"fixes": [], "summary": "No critical or high vulnerabilities found."}
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": """You are a security analysis agent. Analyze the vulnerabilities and recommend fixes.
Return a JSON object with:
- "fixes": a list of fixes, each with:
- "package": the package name
- "action": "update" or "replace"
- "command": the command to run (e.g., "npm install package@latest")
- "explanation": why this fix is recommended
- "summary": a brief summary of the analysis
Guidelines:
- Only recommend fixing critical and high vulnerabilities
- Prefer updating to the latest version over replacing
- If a fix might break the app (breaking changes), note it in the explanation
"""
},
{
"role": "user",
"content": f"Vulnerabilities:\n{json.dumps(critical_vulns, indent=2)}",
},
],
)
return json.loads(response.choices[0].message.content)
def apply_fix(fix):
"""Apply a security fix."""
print(f" Applying fix: {fix['command']}")
result = subprocess.run(
fix["command"].split(),
capture_output=True,
text=True,
cwd=REPO_PATH,
)
return result.returncode == 0
def run_tests():
"""Run the app's tests to verify the fix didn't break anything."""
result = subprocess.run(
["npm", "test"],
capture_output=True,
text=True,
cwd=REPO_PATH,
)
return result.returncode == 0
def deploy_fix():
"""Deploy the fix via the Deployxa MCP server."""
result = call_deployxa("deployxa_deploy_workflow", {"app_id": APP_ID})
return result.get("status") == "success"
def run_security_scan():
"""Run the full security scanning pipeline."""
print(f"[{datetime.utcnow().isoformat()}] Running security scan...")
# Step 1: Scan
audit_result = scan_dependencies()
vulnerabilities = audit_result.get("vulnerabilities", {})
total_vulns = len(vulnerabilities)
critical_count = sum(1 for v in vulnerabilities.values() if v.get("severity") == "critical")
high_count = sum(1 for v in vulnerabilities.values() if v.get("severity") == "high")
print(f" Found {total_vulns} vulnerabilities ({critical_count} critical, {high_count} high)")
if critical_count == 0 and high_count == 0:
send_slack_notification(f"Security scan complete. No critical or high vulnerabilities found. ({total_vulns} total)")
return
# Step 2: Analyze with LLM
analysis = analyze_with_llm(audit_result)
print(f" LLM recommended {len(analysis.get('fixes', []))} fixes")
# Step 3: Apply fixes
applied_fixes = []
for fix in analysis.get("fixes", []):
if apply_fix(fix):
# Step 4: Run tests
if run_tests():
applied_fixes.append(fix)
print(f" Fix applied and tests passed")
else:
print(f" Fix applied but tests failed, reverting...")
subprocess.run(["git", "checkout", "."], cwd=REPO_PATH)
else:
print(f" Fix failed to apply")
# Step 5: Deploy if fixes were applied
if applied_fixes:
deploy_fix()
print(f" Deployed {len(applied_fixes)} fixes")
# Step 6: Report
message = f"Security scan complete!\n\n"
message += f"Vulnerabilities found: {total_vulns} ({critical_count} critical, {high_count} high)\n"
message += f"Fixes applied: {len(applied_fixes)}\n\n"
for fix in applied_fixes:
message += f" - {fix['package']}: {fix['explanation']}\n"
if len(applied_fixes) < critical_count + high_count:
message += f"\n⚠️ {critical_count + high_count - len(applied_fixes)} vulnerabilities remain unfixed. Manual review needed."
send_slack_notification(message, is_alert=critical_count > 0)
# Schedule the scan
schedule.every(SCAN_INTERVAL_HOURS).hours.do(run_security_scan)
# Run immediately, then on schedule
run_security_scan()
while True:
schedule.run_pending()
time.sleep(1)Step 3: Run the pipeline
python security_scanner.pyThe pipeline runs immediately, then every 24 hours. It scans for vulnerabilities, analyzes them with an LLM, applies fixes, runs tests, deploys, and reports via Slack.
Common Pitfalls and Troubleshooting
The first pitfall is auto-fixing without testing. Updating a package might break the app (if the new version has breaking changes), which means you need to test each fix. The fix is to always run tests after applying a fix, and to revert if tests fail. The second pitfall is not prioritizing. npm audit produces many findings, and fixing all of them is impractical. The fix is to prioritize by severity (critical and high first) and to ignore low-severity vulnerabilities. The third pitfall is not creating pull requests. Auto-fixing directly on main is risky, because it bypasses code review. The fix is to create a pull request for each fix, so it can be reviewed before merging. The fourth pitfall is false positives. Some vulnerability reports are false positives (e.g., the vulnerable code is not used). The fix is to use an LLM to analyze whether the vulnerable code is actually used, and to skip the fix if it is not. The fifth pitfall is not monitoring the pipeline. If the pipeline goes down, vulnerabilities go undetected. The fix is to monitor the pipeline (e.g., with a dead man's switch).
Conclusion: Let the Agent Secure Your Dependencies
Manual security scanning is tedious, overwhelming, and does not scale. An agentic security scanning pipeline that scans daily, prioritizes by severity, and auto-fixes critical vulnerabilities is the sustainable solution. With the Deployxa MCP server and an LLM, you can build a security scanning pipeline that keeps your dependencies secure. Stop scanning manually and start automating.
Ready to build your security scanning pipeline? Install the Deployxa MCP server with npm i -g @deployxa/mcp-server, run deployxa-mcp login, and start building. For more on agentic workflows, see our articles on building an AI agent that manages SSL certificates and building an AI agent that generates documentation. Learn about the agentic performance testing pipeline and building an AI agent that manages team access in our companion articles. Explore our free developer tools to speed up your workflow.