skip to content

In GitHub, what is code scanning, and where do CodeQL results show up on a pull request?

level: juniorimportance: should knowfreq 52%

answer

  1. Findings become alerts, not build output
  2. Two surfaces: the job, and the annotations
  3. Diff lines annotate; old code does not
  4. Security tab holds open, fixed, dismissed

basics

~20 s

GitHub code scanning stores static-analysis findings as repository alerts. On a pull request, findings on lines the diff touches appear as inline annotations plus a code scanning results check; every alert, new or old, lists under the repository's Security tab.

solid answer

~50 s

Code scanning is GitHub's home for static-analysis results. The analysis itself runs in a job — usually a GitHub Actions workflow running the `github/codeql-action` steps — which builds a CodeQL database from the code, runs queries over it, and uploads results as SARIF. GitHub turns that upload into **alerts**. On a pull request you see two things: the check for the analysis job (did the scan run?) and a `Code scanning results` check summarising alerts the pull request introduces, with those alerts rendered as inline annotations on the changed lines in Files changed, often with the data-flow path CodeQL followed. Alerts on code the pull request did not touch are not annotated on the diff; they sit in Security → Code scanning with a state of open, fixed, or dismissed. That split is what makes the feature usable on an old codebase.

go deeper

for a junior

Be ready to say plainly what an alert is, that scanning runs as a job in the repository, and that a pull request shows findings on the lines you changed.

for a middle

Explain the mechanism: CodeQL builds a database of the code, queries produce SARIF, GitHub diffs the upload into alerts with open, fixed and dismissed states.

for a senior

Show you know why only diff-local alerts annotate a pull request, and how that lets you enable scanning on a legacy repository without stalling every review.

for a principal

Own the distinction between the three security features and the licensing shape: code scanning on private repositories is a paid capability, so rollout is a budget and policy decision, not just a toggle.

## What code scanning is GitHub code scanning is a repository feature that stores static-analysis findings as **alerts** bound to code locations. It is deliberately tool-agnostic: the wire format is SARIF (Static Analysis Results Interchange Format) 2.1.0, and CodeQL — GitHub's own analysis engine — is the default producer but not the only one. Anything that emits SARIF can fill the same alert list, which is why "code scanning" and "CodeQL" are not synonyms even though people use them interchangeably. ## Where the analysis actually runs Code scanning does not read your repository from the outside like a hosted SaaS scanner. The analysis runs in a job. In the normal case that is a GitHub Actions workflow: `github/codeql-action/init` sets up an extractor for the declared languages, the code is built (or, for languages that support it, analysed without a build), `github/codeql-action/analyze` runs a query suite against the resulting CodeQL database and uploads the SARIF. CodeQL's database is a relational representation of the code — its syntax tree, control flow and data flow — which is why its queries can follow a tainted value from an HTTP parameter through several functions to a sink, rather than just pattern-matching a line. Results can also arrive from outside Actions by uploading SARIF through the code scanning API, which is how teams on another CI system still get alerts on the pull request. ## What appears on a pull request There are two distinct surfaces, and confusing them is the classic junior mistake: 1. **The analysis job's own check.** Green means the scan ran. It says nothing about findings. 2. **The `Code scanning results` check plus annotations.** After the SARIF upload, GitHub compares the results against what it already knows for the base branch. Alerts whose location falls on lines the pull request changed are rendered as inline annotations in the Files changed tab, showing the rule, the message and (for CodeQL) the source-to-sink path. Alerts on untouched code are *not* annotated — they remain in the repository's alert list. That "only what you touched" behaviour is the design decision that lets a team switch scanning on for a twelve-year-old codebase without every pull request drowning in red. The historical backlog stays visible in the Security tab; the pull request shows the delta. ## The Security tab and alert lifecycle Security → Code scanning lists every alert with a rule id, a severity, the branches it has been seen on, and a state: - **Open** — reported by the most recent analysis. - **Fixed** — the code changed and the latest analysis no longer reports it. Nobody clicks anything; the analysis closes it. - **Dismissed** — a human closed it with a reason (false positive, won't fix, used in tests), optionally with a comment. An alert is keyed to a location and rule, so a re-run of the same analysis updates the existing alert rather than creating a duplicate. That is also why a badly behaved third-party SARIF producer can churn alerts: without stable fingerprints, every scan looks like a new finding. ## Who can see and act on it Alert detail is not public: on a public repository anyone can see the code, but the alert list is restricted to users with write access (and security managers). Read-only contributors opening a pull request will see annotations on their diff but cannot triage the repository's alerts. ## What code scanning is not It is static analysis of first-party code. It is **not** dependency vulnerability detection — that is the dependency graph feeding Dependabot alerts — and it is **not** credential detection, which is secret scanning. Candidates who blur the three usually also believe code scanning will find a vulnerable library version, and it will not: CodeQL analyses the code you wrote, not the versions in your lockfile. ## Availability Code scanning is available at no cost on public repositories. On private repositories it is part of GitHub's paid code-security offering (historically sold as GitHub Advanced Security), so "just turn it on" is a licensing conversation as well as a technical one.

  • If the analysis job is green, can the pull request still be reporting security alerts?
    Yes. The analysis job's check only says the scan ran and uploaded results. Whether the pull request introduces alerts is reported separately by the code scanning results check and by the annotations on the diff. Treating a green workflow as "no findings" is a frequent misreading.
  • Who can see the alert list on a public repository?
    The code is public, but alert detail is not. Code scanning alerts are visible to users with write access to the repository, plus roles like security managers. An outside contributor sees annotations on their own pull request diff but cannot browse or triage the repository's alert list.
  • Does code scanning tell you a dependency is on a vulnerable version?
    No. Code scanning analyses first-party source. Vulnerable dependency versions come from the dependency graph and its alerting, and leaked credentials come from secret scanning. Expecting CodeQL to flag an outdated library is the most common category error about the feature.

saying these in an interview costs you the question

  • Thinking code scanning finds vulnerable dependency versions
  • Believing CodeQL alerts appear only after merge
  • Assuming a green analysis job means zero findings
  • Confusing code scanning with secret scanning
  • Claiming every existing alert annotates every pull request

context