post · February 2, 2025 · 2 min read
Automating SAST with GitHub Actions and CodeQL
By Saleh Elnagar
Why CodeQL Belongs in Your DevSecOps Pipeline
Static analysis is most effective when it runs where developers work. GitHub Actions provides native integration with CodeQL, enabling you to:
- Continuously scan every pull request and main branch commit.
- Use a curated ruleset aligned with OWASP Top 10 and CWE Top 25.
- Baseline existing risk so new findings are prioritized.
- Automate triage with code owners and security champions.
Reference Workflow
The workflow below scans supported languages on a nightly cadence and for every pull request targeting main. It stores the CodeQL database as an artifact for deeper triage when needed.
name: codeql-sast
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
schedule:
- cron: "0 1 * * *" # 01:00 UTC nightly
permissions:
contents: read
security-events: write
actions: read
jobs:
analyze:
name: Run CodeQL Analysis
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: ["javascript", "python"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"
- name: Upload CodeQL Database
uses: actions/upload-artifact@v4
with:
name: codeql-${{ matrix.language }}-database
path: ${{ runner.temp }}/codeql_databases/${{ matrix.language }}
Pushing Quality Findings to the Right Teams
GitHub converts CodeQL alerts into code scanning findings. Tighten the feedback loop by:
- Using
CODEOWNERSto auto-request reviews from the feature team. - Configuring branch protection to require a clean security scan before merging.
- Routing alerts to Slack or Microsoft Teams via
security-eventswebhooks.
Tip: Leverage GitHub’s autofix beta for supported languages to auto-generate remediation pull requests.
Managing Technical Debt with Baseline Behavior
Legacy code often ships with unresolved findings. Instead of overwhelming developers, baseline the existing alerts:
- Run a full scan on
mainand export alerts with the GitHub Security REST API. - Suppress accepted risks using
.codeql/suppressions.ymlwith business justification. - Track the delta in a dashboard (e.g., GHAS Security Overview or custom datamart).
Operational Guardrails
To keep scanning fast, deterministic, and secure:
- Cache CodeQL bundles in an internal artifact registry or GitHub’s built-in cache.
- Pin actions by commit SHA and enable Dependabot to auto-upgrade.
- Add
permissionsblock to all jobs and default toreadunless a step needs more. - Use GitHub-hosted runners for predictable environments; self-hosted runners need additional hardening.
Measuring Success
Add CodeQL coverage and MTTR to your DevSecOps scorecard. Track:
- Percentage of critical repos with CodeQL enabled.
- Median time to remediate high-severity findings.
- False positive rate per workflow run.
- Reduction in exploitable vulnerabilities across releases.
By automating SAST in GitHub Actions you move security left without overwhelming engineers, keeping the feedback loop predictable and actionable.
Quick AI Summary
Why CodeQL Belongs in Your DevSecOps Pipeline Static analysis is most effective when it runs where developers work. GitHub Actions provides native integration with CodeQL, enabling you to: Continuously scan every pull request and main branch commit.
Original article body above remains unchanged.
Continue Reading
Related Posts
Repository: https://github.com/SalehElnagar/azure-terraform-conventions This article walks through how to think about Azure naming conventions and how to turn those decisions into code using the azure-terraform-conventions GitHub repository. That repo contains: The goal is not “just use whatever the repo does”. The goal is: capture your organization’s naming decisions once, codify them with this library, and then […]
Reusable workflows enable security platform teams to codify guardrails once and roll them out to every repository. This article walks through building a multi-stage pipeline where security controls move as code, not documentation. Architectural Pattern Producer Repo Hosts versioned reusable workflows (.github/workflows/*.yml) that encapsulate validation, testing, and deployment steps with security baked in. Consumer Repos […]
Not a chance. I outsource that memory to kubectl and keep my brain for coffee orders and incident timelines. ☕🚀 Here’s how I look clever without memorizing a phone book of resources: 1) See every resource + its short name This shows NAME, SHORTNAMES, APIGROUP, NAMESPACED, KIND. 2) When you remember the full name and […]
Get New Playbooks Weekly
Join the newsletter for practical Azure, Terraform, and DevSecOps guides. One actionable email per week.
Comments
Enable comments by setting NEXT_PUBLIC_GISCUS_* environment variables.