GitHub Actions Security Scan Workflow Builder

Add CodeQL and npm audit scanning to your CI pipeline

Generates a GitHub Actions workflow YAML with CodeQL static analysis, an npm audit step, and an optional Snyk scan, triggered on push to main and on pull requests, with a scheduled weekly run for ongoing coverage. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is CodeQL and why include it?

CodeQL is GitHub's static analysis engine that queries your code for security vulnerabilities like injection, path traversal, and unsafe deserialization. It runs free on public repos and on private repos with GitHub Advanced Security, and surfaces findings directly in the repo's Security tab.

The GitHub Actions Security Scan Workflow Builder generates a CI workflow that scans both your code and your dependencies on every change. It wires up CodeQL static analysis for code vulnerabilities, an npm audit step for known dependency advisories, and an optional Snyk scan, triggered on pushes to main, on pull requests, and on a weekly schedule.

The three scanning layers and what each catches

CodeQL (static code analysis)

CodeQL is GitHub’s semantic code analysis engine. Unlike linters that check syntax and style, CodeQL treats your code as data — it builds a queryable database of your codebase and runs security queries against it to find patterns like:

  • SQL injection and XSS in web applications
  • Path traversal vulnerabilities
  • Insecure deserialization
  • Use of unsafe APIs (e.g. eval, dangerouslySetInnerHTML)
  • Authentication bypass patterns

Results appear in the repository’s Security → Code scanning tab with line-level annotations. CodeQL runs free on public repositories; private repositories require GitHub Advanced Security.

npm audit (dependency vulnerabilities)

npm audit compares your package-lock.json against the npm advisory database and flags packages with known CVEs. The workflow runs it with a severity threshold (--audit-level=high by default) so the job fails only for serious advisories, not every low-severity warning in deep transitive dependencies. This catches the class of vulnerability that affects your users even if your own code is clean — a compromised or vulnerable dependency in your supply chain.

Snyk (optional, deeper dependency scanning)

Snyk provides a more detailed dependency analysis than npm audit, with fix suggestions and a broader vulnerability database. It requires a free Snyk account and a SNYK_TOKEN added as a repository secret. It also scans Docker images and IaC (Terraform, Kubernetes) if you use those.

How the workflow is structured

name: Security
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 6 * * 1'    # Weekly Monday 06:00 UTC
permissions:
  security-events: write
  contents: read
jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: javascript
      - uses: github/codeql-action/autobuild@v3
      - uses: github/codeql-action/analyze@v3
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm audit --audit-level=high

Why a scheduled weekly scan?

Your code may not change for weeks, but new vulnerabilities are disclosed against dependencies you already use. A weekly cron scan (schedule trigger) catches these newly disclosed advisories without waiting for the next code change to trigger CI. It’s also the only way to catch vulnerabilities that are disclosed after a PR merges but before the next code push.

Practical setup tips

  • security-events: write is required. Without this permission, CodeQL’s analyze step cannot upload results to the Security tab. The builder adds it automatically.
  • Start the audit threshold at high. Transitive dependencies often carry low-severity advisories that are not exploitable in your context. Start at high (or even critical) and tighten once you’ve resolved the serious ones.
  • Add SNYK_TOKEN before enabling Snyk. Without the token, the Snyk step fails with an authentication error on every run — add the secret first.
  • CodeQL’s autobuild may need help. For compiled languages (Java, C++), autobuild runs heuristics to build the code. If it fails, replace it with your actual build command. For JavaScript/TypeScript, autobuild is usually not needed.
  • Review findings, don’t just dismiss them. CodeQL findings are ranked by severity. Even a “medium” finding deserves a read — some are exploitable, and dismissing them without review defeats the purpose of running the scan.