Join our Newsletter — 33% off our NHI Course
Home› Guides› CodeQL Guide: Setup Choices, Query Packs, Custom Models…
Guide Application Security

CodeQL Guide: Setup Choices, Query Packs, Custom Models and Governance

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 14 min read
On this page

CodeQL is often switched on with one click and then left alone, which means it scans with the default query suite, misses the frameworks it does not recognise, and lets anyone with write access quietly dismiss what it finds. CodeQL is GitHub's semantic code analysis engine: it builds a database from your code and runs queries against it, and results appear as code scanning alerts. This guide covers the decisions that determine how much value it delivers: default versus advanced setup versus the CLI in external CI, build modes, query suites and packs, threat models, custom model packs for in-house frameworks, alert governance, tokens and workflow permissions, merge protection, licensing and metrics. It is for application security engineers and platform teams running GitHub at organisation scale. For where CodeQL sits among other free tools, see the Open Source AppSec Tools Landscape Guide.

Key takeaways

  • Start with default setup, graduate deliberately: default setup covers most repositories with no workflow file; move to advanced setup only where you need manual builds, custom packs pinned per repository, or path filtering.
  • The query suite is a risk decision: default is high precision, security-extended adds lower-precision and lower-severity queries, and security-and-quality (advanced setup only) adds maintainability checks.
  • Unmodelled frameworks are blind spots: if your code reads input through an in-house library CodeQL does not know, taint never starts; model packs and the remote-and-local threat model close that gap.
  • Govern dismissals, not just findings: anyone with write access can dismiss an alert across all branches, so require dismissal comments, review them, and block merges with rulesets at an agreed severity.
  • Tokens and licences are part of the design: workflows need only security-events: write (plus contents: read for private repositories), external CI uploads need a scoped token, and CodeQL on non-open-source code requires GitHub Code Security.

How CodeQL code scanning works

CodeQL works in three steps: it creates a database that represents the codebase (extracting source, and for compiled languages optionally observing the build), runs queries against that database, and uploads the results in SARIF format to GitHub, where they become code scanning alerts. Queries are written in the CodeQL language and most security queries use data flow and taint tracking: they model sources (where untrusted data enters), sinks (where it becomes dangerous, such as a SQL call) and sanitisers, then report paths from source to sink.

Supported languages, per GitHub documentation: C/C++, C#, Go, Java/Kotlin (java-kotlin), JavaScript/TypeScript (javascript-typescript), Python, Ruby, Rust, Swift and GitHub Actions workflows. GitHub warns that other languages such as PHP and Scala are not supported, and that running CodeQL on them may give no alerts or incomplete analysis, so those repositories need another SAST tool. See the Semgrep Guide.

Build modes

Build modeHow it worksTrade-off
noneDatabase created without building; required for interpreted languages, available for some compiled ones (C#, Java, Rust; C/C++ in preview)Fast and simple, but may miss alerts where code is generated during compilation or dependencies cannot be downloaded; not yet available for Swift, Go or Kotlin
autobuildCodeQL guesses the build with heuristicsSimple; when it succeeds results equal manual mode; fails on non-standard builds
manualYour own build steps run between the init and analyze stepsTypically the most precise results; more set-up and slightly longer runs

Choosing default setup, advanced setup or external CI

OptionBest forWhat you controlWatch out for
Default setupMost repositories; organisation-wide rollout through security configurationsLanguages, query suite (default or extended), threat model, runner labels, model packs from .github/codeql/extensions or organisation settingsEnabling it overrides an existing advanced configuration and blocks uploads through the CodeQL analysis API; weekly scheduled scans stop after six months without pushes or pull requests
Advanced setup (workflow with github/codeql-action)Compiled code needing manual builds, monorepos, pinned packs, custom triggers such as merge_groupEverything: triggers, matrix per language, build-mode, queries, packs, config-file, categoryEach workflow is code that needs maintenance and review; drift between repositories
CodeQL CLI in external CIBuilds that run in Jenkins, GitLab CI, Azure Pipelines or similarFull CLI; results uploaded with codeql github upload-resultsNeeds a long-lived or app-issued token with code scanning write access stored in that CI system
  • Small organisations: enable default setup on every repository, pick the extended suite for internet-facing services, and review alerts weekly. That is enough until a build fails or a framework goes unmodelled.
  • Large organisations: use organisation security configurations to apply default setup at scale, keep advanced setup for an approved list of complex repositories, and publish organisation model packs centrally so every repository benefits.
  • Who can enable it: GitHub lists repository owners, organisation owners, security managers and users with the admin role. Restrict this so that teams cannot switch off scanning without a record.

Query suites, query packs and threat models

SuiteContentsAvailable inUse when
defaultHighly precise queries with few false positivesDefault and advanced setupFirst rollout, teams new to SAST
security-extendedDefault plus queries with slightly lower precision and severityDefault setup ("Extended") and advanced setupInternet-facing services, regulated code, once triage capacity exists
security-and-qualityExtended plus maintainability and reliability queriesAdvanced setup onlyTeams that want one tool for quality and security and accept more noise

Query packs add queries beyond the suites, published by GitHub, the community or your own team. In advanced setup they are listed under packs:, and GitHub documents version pinning in the form scope/[email protected] (exact) or scope/pack@~3.2.1 (compatible range). If no version is given, the latest version is downloaded, which means a pack update can change results without any change in your repository. Pin packs for reproducibility and update them through a reviewed pull request. Private packs need a token with access to the registry.

Threat models decide which inputs count as tainted. The default treats remote network requests as sources. The remote and local model also treats command-line arguments, environment variables, file systems and databases as sources, which suits CLIs, batch jobs and services that read files from untrusted parties. GitHub lists threat models as public preview for Java/Kotlin and C# only, so check current status before relying on it. Expect more alerts when local sources are enabled and plan triage time.

Custom models: extending CodeQL to your frameworks

CodeQL ships models for popular libraries. In-house HTTP frameworks, data access layers and wrappers around dangerous APIs are unknown to it, so a query cannot see that InternalRequest.param() returns attacker data or that Db.rawExec() runs SQL. The fix is a model pack: a CodeQL pack of YAML data extensions that declare additional sources, sinks and summaries (flow through a method) for a language library. Model packs are in public preview for C/C++, C#, Java/Kotlin, Python, Ruby and Rust; the CodeQL model editor in Visual Studio Code supports C#, Java/Kotlin, Python and Ruby.

  1. Find the gaps: list internal frameworks that handle requests, files, queues or database calls. A useful signal is a service with real input handling and zero data-flow alerts.
  2. Model with the editor: open the framework in the model editor, mark methods as sources, sinks or summaries, and save the generated extension files into a pack with its codeql-pack.yml.
  3. Test on one repository: copy the pack into .github/codeql/extensions; default setup detects it automatically (and advanced setup also uses that directory). Seed a known vulnerable test case and confirm an alert appears.
  4. Publish for the organisation: publish the pack to the GitHub Container registry and list it under the organisation's Advanced Security global settings ("Expand CodeQL analysis"), so every repository using default setup picks it up.
  5. Version and own it: treat the pack as code: owners, review, release notes, and a regression test repository.

Custom queries (not only models) suit organisation-specific rules such as "no calls to the deprecated crypto wrapper". For simple pattern rules, a pattern engine is quicker to write; use CodeQL queries where data flow matters.

Roles, permissions and alert governance

  • Dismissal power: GitHub documents that users with write access can dismiss alerts. A dismissal closes the alert in all branches and the same code does not raise it on the next scan. Without review, dismissal becomes the fastest way to make a dashboard green.
  • Require reasons: make a dismissal comment mandatory in your process, and pull dismissed_comment and dismissal reasons through the REST API into a monthly review of dismissals by repository and user.
  • Delegate approval where available: GitHub offers delegated alert dismissal with a review of dismissal requests; where licensed, use it for production repositories so a security reviewer approves each dismissal.
  • Security managers: give the organisation security team the security manager role rather than owner rights, so they can manage alerts and settings across repositories without full administrative control.
  • Merge protection: add a ruleset with "Require code scanning results" for CodeQL. GitHub's thresholds are "None", "Errors", "Errors and Warnings" or "All" for alerts, and "None", "Critical", "High or higher", "Medium or higher" or "All" for security alerts. A pull request is blocked when a required tool finds an alert at or above the threshold, its analysis is still running, or the tool is not configured. "High or higher" is a common starting point.
  • Autofix: Copilot Autofix can propose a fix and open a draft pull request for backlog alerts on the default branch. GitHub describes it as best effort; treat its output as a suggestion that still needs code review. See the AI-Generated Code Review Guide.

Integrations, tokens and service accounts

Code scanning has its own non-human identities, and they deserve the same care as any deployment credential.

IntegrationCredentialMinimum accessHardening
Advanced setup workflowWorkflow GITHUB_TOKENsecurity-events: write; add contents: read in private repositories (and actions: read where the workflow needs it)Set an explicit permissions: block per job; do not run CodeQL on pull_request_target with checkout of untrusted code
CLI in external CIGitHub App installation token or a personal access token with code scanning alerts writeOnly the repositories scannedPrefer a GitHub App over a personal token tied to a person; pass it with --github-auth-stdin from the CI secret store rather than a plain variable
Private query or model packsToken with package read access (the registries input or GITHUB_TOKEN)Read only on the pack registrySeparate from the upload token; pin pack versions
Third-party SARIF uploadupload-sarif action with workflow tokensecurity-events: writeGive each tool a distinct category so results do not overwrite each other
Self-hosted or larger runnersRunner registrationOnly the runner group that needs itEphemeral runners; the build step executes repository code with the runner's network access

An upload token that can write code scanning results can also be used to flood or close alerts, so a leak is an integrity problem, not just a confidentiality one. See the GitHub Personal Access Tokens Security Guide and the GitHub and GitHub Actions Security Guide.

Licensing

The CodeQL CLI is licensed under the GitHub CodeQL Terms and Conditions. They permit academic research and analysis of an open source codebase (one released under an OSI-approved licence), and automated analysis, CI or CD only for open source codebases hosted and maintained on GitHub.com. Using CodeQL in automated analysis of private or non-open-source code requires a commercial licence, which for GitHub repositories means GitHub Code Security on GitHub Team, Enterprise Cloud or Enterprise Server. Running the CLI in an external CI system against private code without that licence breaches the terms, so confirm licensing before a proof of concept.

Logging, detection and measurement

  • Coverage drift: query the code scanning APIs or security overview for repositories with no analysis in the last 7 days, failed analyses, or languages detected but not scanned.
  • Configuration changes: alert on code scanning being disabled, a switch from extended to default suite, or rulesets removed. Feed the organisation audit log into your SIEM; see the GitHub Audit Log Detection Guide.
  • Dismissal patterns: flag users or repositories with unusually high dismissal rates, or dismissals of critical alerts without comment.
  • Workflow tampering: CODEOWNERS on .github/workflows/ and .github/codeql/ so a pull request cannot silently add paths-ignore for the vulnerable directory.
MetricWhy it mattersSuggested target
Share of active repositories in supported languages with a successful analysis in the last 7 daysCoverage95% or more
Median time to fix critical and high alerts on the default branchRemediation speedWithin your vulnerability SLA
Share of alerts dismissed as false positive, by queryNoise and model gapsInvestigate any query above 30%
Share of production repositories with merge protection enabledPrevention, not detection100% for production
New alerts introduced per 100 merged pull requestsWhether pull request scanning is shifting fixes leftTrending down

For programme-level metrics and how to report them, see the AppSec Programme Metrics Guide, and for triage workflow the SAST Triage and False Positive Management Guide.

Hardening baseline and rollout

  1. Pilot: enable default setup with the default suite on 10 to 20 representative repositories; measure run time, failures and false positive rates for two weeks.
  2. Roll out: apply a security configuration at organisation level; fix failed analyses (usually build mode) before counting coverage.
  3. Raise the bar: switch internet-facing and regulated services to the extended suite; enable remote and local threat models where supported and justified.
  4. Model: build and publish model packs for the top internal frameworks.
  5. Enforce: add merge protection at "High or higher" for security alerts, first in evaluate mode on rulesets where available, then active.
  6. Rollback: if merge protection blocks delivery unexpectedly, lower the threshold or set the ruleset to evaluate rather than disabling code scanning; for a bad pack release, pin the previous version.

Common misconfigurations

  • Unpinned packs: results change overnight when a pack updates, and nobody can explain why an alert appeared or vanished.
  • Build mode none on code generation heavy projects: generated sources are missing from the database, so whole layers are never analysed.
  • Over-broad paths-ignore: excluding src/legacy to cut noise, which is exactly where the oldest vulnerabilities live.
  • Write-all workflow permissions: a CodeQL job running with a token that can push code or publish releases, rather than security-events: write only.
  • Silent stops: repositories whose scheduled scans stopped after six months of inactivity, still counted as "covered", or whose analyses fail for every language and so run no scans.
  • Personal tokens for CI upload: a token owned by one engineer that breaks, or stays live, when they leave. Secrets in CI systems are a recurring breach route, as the CircleCI breach showed when customer CI secrets were exfiltrated.

Framework mapping

FrameworkReferenceHow CodeQL supports it
NIST SP 800-53 Rev. 5SA-11 Developer Testing and Evaluation; SA-11(1) Static Code Analysis; SA-15 Development Process, Standards, and ToolsStatic analysis in the pipeline with documented configuration
NIST CSF 2.0PR.PS-06; ID.RA-01Secure development practices monitored; vulnerabilities identified and recorded
ISO/IEC 27001:2022 Annex AA.8.25 Secure development life cycle; A.8.28 Secure coding; A.8.29 Security testing in development and acceptanceEvidence of testing and coding standards
CIS Controls v8.116.12 Implement code-level security checksStatic analysis tooling
MITRE ATT&CKT1195.001 Compromise Software Dependencies and Development ToolsProtecting the scanning workflow and packs themselves

Practitioner checklist

  • Enable default setup across all repositories in supported languages; route unsupported languages to another SAST tool.
  • Choose the query suite per risk tier and record the decision.
  • Fix failed analyses and choose build modes deliberately; use manual builds where generated code matters.
  • Pin query and model pack versions; update through reviewed pull requests.
  • Build model packs for in-house frameworks and publish them organisation-wide.
  • Set least-privilege workflow permissions and use a GitHub App token for external CI uploads.
  • Require dismissal comments, review dismissals monthly, and use delegated dismissal where licensed.
  • Add merge protection on production repositories at an agreed severity threshold.
  • Monitor coverage, failures and configuration changes; confirm licensing for any non-GitHub CI use.

Standards and references

Related NHI Mgmt Group resources: Open Source AppSec Tools Landscape Guide · Semgrep Guide · SAST Triage and False Positive Management Guide · GitHub and GitHub Actions Security Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.