February 10, 2026
6 mins

Six Layers of Security Scanning in 24 Hours: Why Insecure AI Code Is Now Inexcusable

Five layers of security scanning architecture diagram
Image
Image

The conversation around AI-generated code has a blind spot. Everyone debates whether AI writes secure code. Almost nobody talks about AI’s ability to detect, manage, and remediate insecure code — regardless of who wrote it.

Yesterday morning, our production application had minimal security scanning — just Dependabot and GitHub’s secret scanning. By this morning, we had six layers of continuous vulnerability detection, a baseline report of every finding, and the single production vulnerability already fixed. The total human effort was a conversation with Claude Code.

This isn’t a story about writing code faster. It’s about managing code better.

The Setup: What We Built in 24 Hours

We needed a proper security scanning posture for our production Node.js application, deployed via Docker to cloud infrastructure. The goal was straightforward: continuous visibility into vulnerabilities across dependencies, source code, container images, and supply chain.

Here’s what’s now running nightly:

1. CodeQL — Deep Semantic Analysis
GitHub’s own static analysis engine. It builds a complete data-flow model of the codebase and traces tainted input from HTTP requests through to file operations, database queries, and HTML output. This is the heaviest scanner — it understands our custom sanitisation functions through a bespoke query we wrote. It catches the subtle vulnerabilities that pattern matching misses.

2. OSV Scanner — Dependency Vulnerabilities (Google)
Scans every lockfile against the Open Source Vulnerabilities database. If a dependency has a known CVE, this finds it. Runs nightly because new vulnerabilities are disclosed constantly — a clean scan today means nothing about tomorrow.

3. Trivy — Dependency Vulnerabilities (Aqua Security)
A second dependency scanner using a different vulnerability database. Yes, we run two. They use different sources, different heuristics, and different detection logic. The overlap is intentional — for security scanning, redundancy is a feature, not waste.

4. Semgrep — Pattern-Based Static Analysis
Runs 543+ community OWASP rules looking for common anti-patterns: path traversal, injection, insecure defaults, missing security headers, shell=true in subprocess calls. Faster and shallower than CodeQL — catches the obvious things that deep analysis might over-think.

5. Dependabot — Proactive Dependency Updates
Monitors npm packages, GitHub Actions versions, and Docker base images. Opens PRs automatically when updates are available. This is the preventive layer — keeping dependencies current before vulnerabilities are even disclosed.

6. GitHub Secret Scanning — Credential Detection
Scans every commit for accidentally exposed API keys, tokens, passwords, and other credentials. This was one of the two tools we already had running before this exercise. It’s free, it’s automatic, and it catches the single most common security mistake in any codebase — shipping secrets to version control.

Every scanner uploads results in SARIF format to GitHub’s Security tab. One dashboard, all findings, all scanners. Alerts open when issues are detected. Alerts close when code is fixed. No manual tracking, no spreadsheets, no “we’ll get to it.”

For Vibe Coders

Don’t Start With Five Scanners

If you’re figuring out where to begin with security scanning, resist the urge to install everything at once. Five scanners will noisily tell you the same issue five times. You’ll drown in alerts and fix nothing. Instead, layer up progressively:

  1. Start with Dependabot and Secret Scanning. Both are free on any GitHub repository. Enable them today. They’ll catch leaked credentials and outdated dependencies — the two most common vulnerability classes. Clean up every finding before moving on.
  2. Switch to a GitHub Organisation and turn on CodeQL. At $4/month per developer, you get GitHub’s deep semantic analysis — the same engine that powers security scanning at Microsoft. Clean up those findings too.
  3. Then add the rest. Once your baseline is clean, layer on Trivy, OSV, Semgrep, and whatever else makes sense for your stack. At this point, new findings are genuinely new — not duplicates of problems you already know about.

The goal is a clean baseline at each layer before adding the next. Progressive security beats noisy security every time.

The Remediation: Fix While You Scan

Setting up scanners is one thing. What happened next is the part that would have been unthinkable two years ago.

The baseline scan found a single production vulnerability — axios 1.13.2 had a denial-of-service CVE. Claude Code identified it, upgraded the dependency, verified the build still compiled, re-ran the scanner to confirm zero findings, and updated the documentation. In the same conversation where it set up the scanners.

It also identified that 8,277 Semgrep findings across the full repository were overwhelmingly noise — 7,381 were missing SRI attributes on generated HTML documentation files, not application code. It separated signal from noise, excluded the irrelevant directories, and configured the scanners to focus on production code.

This is the shift. Not AI writing code, but AI operating as a security engineer — triaging findings, distinguishing false positives from real vulnerabilities, applying fixes, verifying the fix worked, and documenting everything.

Why Six Layers, Not One

A reasonable question: isn’t one scanner enough?

No. Each tool sees differently:

  • CodeQL understands data flow but is slow and needs careful tuning
  • OSV and Trivy use different vulnerability databases — running both closes gaps
  • Semgrep catches pattern-level issues (like shell=True in Python subprocess calls) that semantic analysers may not flag
  • Dependabot works proactively, before vulnerabilities are disclosed
  • Secret Scanning catches leaked credentials that no code-quality scanner would flag

A path traversal vulnerability in an Express route might be caught by CodeQL’s data-flow analysis, Semgrep’s pattern matching, or both. A newly disclosed CVE in a transitive dependency might appear in Trivy’s database before OSV’s, or vice versa. A Docker base image might ship with a vulnerable system library that no source-code scanner would find.

Defence in depth isn’t a theoretical principle. It’s the practical reality that no single tool catches everything.

The SOC 2 Angle

In a previous life, I led these security programmes before AI existed. I know exactly what this work costs in human terms.

Establishing automated vulnerability scanning, configuring exclusion policies, documenting the rationale for each suppressed finding, creating baseline reports, setting up continuous monitoring, and writing the operational documentation — this is a core component of SOC 2 Type II compliance. Specifically, it addresses the Common Criteria around system monitoring (CC7.1), risk assessment (CC3.2), and change management (CC8.1).

Traditionally, this work requires:

  • A security engineer or consultant who understands both the scanning tools and your specific architecture
  • 2–3 weeks minimum to evaluate, select, and configure scanners
  • Another 2–3 weeks to tune false positives, establish baselines, and write suppression policies
  • Ongoing documentation that auditors can review
  • Regular evidence collection showing scans actually run and findings are addressed

Six weeks of expert work. Conservatively. Often longer, because the person configuring the scanners rarely understands the application deeply enough to tune the results without extensive back-and-forth with the development team.

We did it in 24 hours. Not because the work is trivial — the same decisions were made, the same configurations were written, the same documentation was produced. The difference is that the AI doing the work has full context of the codebase, understands the architecture, and can evaluate each finding against the actual code.

This doesn’t replace the need for a human who understands what good security looks like. It eliminates the mechanical overhead that made good security expensive.

The Argument People Get Backwards

The prevailing concern is that AI generates insecure code. That’s not wrong — careless use of any tool produces careless results. But it misses the larger picture.

Before AI, writing secure code required expertise. Setting up security scanning required different expertise. Maintaining those scans required ongoing effort. Remediating findings required yet more expertise. Most teams had none of these in sufficient quantity, so they shipped with no scanning at all and hoped for the best.

The attack surface wasn’t smaller. It was just invisible.

Now, the same AI that can write code can also:

  • Configure six layers of security scanning in an afternoon
  • Triage thousands of findings and separate real vulnerabilities from noise
  • Fix the real ones immediately
  • Generate the documentation an auditor needs
  • Explain why each exclusion policy exists

The security posture hasn’t decreased. It’s increased dramatically — because the barrier to implementing proper controls has collapsed.

Sloppy, insecure code is still entirely possible. What’s no longer possible is the excuse that you couldn’t afford to check.

From Writing Code to Managing Code

This is the maturity curve most teams haven’t reached yet. AI adoption in software development has focused almost entirely on generation — write code faster, build features quicker, ship more. The next phase is management — using AI to maintain, monitor, secure, and operate the code it helped create.

The setup we built isn’t clever. It’s six scanners configured through GitHub Actions, running on a cron schedule, uploading to a standard dashboard. Any competent security engineer could have done the same thing manually. The difference is time, context, and accessibility.

When AI can both create the vulnerability and find it, when it can both introduce the insecure dependency and upgrade it, when it can both write the code and write the scanner configuration that catches problems in that code — the entire economics of software security change.

Security scanning is no longer a specialised discipline requiring dedicated headcount. It’s a commodity capability that any team can implement in a day. The scanners are free. The CI platform is free. The AI that configures and maintains them is a conversation.

The only remaining question is whether you choose to use it.

What We’re Running

For teams wanting to replicate this, here’s the concrete setup:

LayerToolWhat It DoesSchedule
Semantic analysisCodeQLData-flow tracing across JS/TS, C#, ActionsWeekly + push/PR
Dependency scanOSV ScannerGoogle’s vulnerability databaseNightly
Dependency scanTrivyAqua Security’s vulnerability databaseNightly
Static analysisSemgrep543+ OWASP pattern rulesNightly
Dependency updatesDependabotnpm, GitHub Actions, Docker base imagesEvery push
Credential detectionSecret ScanningAPI keys, tokens, passwords in commitsEvery push

All results surface in GitHub Security > Code scanning alerts. One dashboard. No context switching.

Total cost: zero. Total setup time with Claude Code: one working session.

The six-week security engagement is now a Tuesday afternoon.

What’s Next

The obvious next steps are SBOM generation and signing our container images — building trusted artifacts so that downstream consumers can verify provenance. We haven’t done this yet, and we don’t need to today. We control every part of the deployment supply chain end-to-end: we build the images, we push them, we deploy them. There’s no third party consuming our artifacts who needs to verify where they came from.

When that changes — when we distribute images to customers, or when compliance frameworks start requiring signed artifacts — it’ll be straightforward to add. The infrastructure is already there. The GitHub Actions pipelines, the security scanning dashboard, the CI/CD workflow. Adding SBOM generation and image signing is an afternoon’s work on top of what we’ve already built. But doing work you don’t need yet is its own kind of waste.