Which taint-tracking ruleset actually ran over this repository — the query suite, the languages selected, and the threat model that decides what counts as an untrusted source — together with whether the recurring scan is still scheduled, when it last ran per analysed language, and how many rules were in the run; and then the open findings in the injection families SI-10 is about, identified by the CWE tags the queries carry. The ruleset and the freshness are the load-bearing half: a finding names a sink that exists, but only the run record says the absence of findings means anything at all.
The API supplies the facts, but a human judgement against a documented baseline turns them into evidence.
Fetch
$ gh api --paginate "/orgs/<ORG>/code-security/configurations"$ gh api --paginate "/orgs/<ORG>/code-security/configurations/<CONFIGURATION_ID>/repositories?status=attached,enforced&per_page=100"$ gh api "/repos/<ORG>/<REPO>/code-scanning/default-setup"$ gh api --paginate "/repos/<ORG>/<REPO>/code-scanning/analyses?tool_name=CodeQL&ref=refs/heads/<DEFAULT_BRANCH>&per_page=100"$ gh api --paginate "/orgs/<ORG>/code-scanning/alerts?state=open&tool_name=CodeQL&per_page=100"$ gh api -H "Accept: application/sarif+json" "/repos/<ORG>/<REPO>/code-scanning/analyses/<ANALYSIS_ID>"Expected output
Report names used below, and the command each comes from: `configurations` is the first, `configuration-repositories` the second, `default-setup` the third, `analyses` the fourth, `alerts-open` the fifth, and the sixth returns SARIF rather than a report this recipe asserts on. RUN COMMANDS 3, 4 AND 6 ONCE PER REPOSITORY. Neither default setup nor analyses has an organization-scoped endpoint; the alerts endpoint does, and it returns the owning `repository` on each alert, so the findings arrive in one list while the run record is assembled one repository at a time. AND READ THE TWO RUN-RECORD CLAUSES ONCE PER ANALYSED LANGUAGE, not once per repository. GitHub documents `category` as what distinguishes "multiple analyses for the same tool and commit, but performed on different languages or different parts of the code", and the endpoint has NO `category` filter — its filters are `tool_name`, `tool_guid`, `pr`, `ref` and `sarif_id`. So on a Java-plus-JavaScript repository the newest row is whichever language finished last, and a clause reading position zero of the unfiltered list can be satisfied by a run that says nothing about the language carrying the risk. The command pins `ref` to the default branch for the same class of reason — without it a `refs/pull/N/merge` analysis can be the newest row — and `<CATEGORY>` in the two clauses below is a placeholder the collector fills once per entry in `default-setup.languages`. The exact category string default setup emits per language is NOT documented and was not verified; read it off the `category` field of the response rather than constructing it. From `default-setup`, the fields this recipe exists to read — `query_suite` (`default | extended`), `threat_model` (`remote | remote_and_local`) and `languages` (from `actions, c-cpp, csharp, go, java-kotlin, javascript-typescript, python, ruby, swift`) — plus `state` (`configured | not-configured`), `updated_at` and `schedule` (`weekly | null`). From `analyses`, `created_at`, `rules_count`, `results_count`, `category`, `commit_sha`, `ref`, `error`, `warning` and the `tool` object; `sort` accepts only `created` and `direction` defaults to `desc`, so the first row of any category-filtered projection is that category's newest run. From `alerts-open`, alerts whose `rule` object carries `tags` — the field the CWE clause below reads. CodeQL query metadata puts CWE classification in that array in the form `external/cwe/cwe-089`, verified on three query help pages: `js/sql-injection` carries `security`, `external/cwe/cwe-089`, `external/cwe/cwe-090` and `external/cwe/cwe-943`; `js/command-line-injection` carries `correctness`, `security`, `external/cwe/cwe-078` and `external/cwe/cwe-088`; `js/reflected-xss` carries `security`, `external/cwe/cwe-079` and `external/cwe/cwe-116`. Two things about that array decide how the clause below is written. `tags` is documented as "array of string or null", and a null array is the case a `contains()` filter cannot state an opinion about — so a separate clause counts the rows that have no array at all, rather than letting them pass silently. And the alerts endpoint has NO server-side tag filter — its filters are `tool_name`, `tool_guid`, `state`, `severity`, `sort`, `direction` and `assignees` — so the CWE narrowing is a client-side filter over a FULL page walk, and a collector that fetches one page of thirty and filters it has produced a smaller answer rather than a filtered one. The command passes `tool_name=CodeQL` so the list holds only rows from the analyses the run-record clauses measure. The sixth command returns the run's SARIF, whose `runs[].tool.driver.rules[]` is the closest thing available to a list of the queries that actually executed. GitHub documents the response as "a subset of the analysis data that was uploaded", which is why nothing below asserts on it: it is collected so a human can read which rules were present, and a subset is not a population.
Assertions — what makes it a pass
| Field | Must be | For | Proves |
|---|---|---|---|
| default-setup.state | eq "configured"This repository has code scanning configured, read from the repository rather than from an organization configuration that claims to govern it. First clause because it is the precondition for every other statement here: on `not-configured` the analyses list is empty, the alert clause is vacuously green, and the recipe has measured nothing. | every row | SI-10 |
| default-setup.languages[?@=='<LANGUAGE>'] | [0] | existsThe language this part of the boundary's code is written in is among those default setup selected. Read once per language on the provider's own list of implementation languages, which is external to every response here — that list is the whole point, because `languages` is a SELECTION and a repository whose Go service was never selected is `configured`, scheduled, fresh, rule-carrying and completely silent about that service. This is the one limb of SI-10's coverage question that is writable at all, and it is writable only because the comparison value comes from outside; nothing in this output would reveal the omission. | every row | SI-10 |
| default-setup.schedule | eq "weekly"The recurring scan for this repository is still scheduled. GitHub documents the schedule switching itself off — "If no pushes and pull requests have occurred in a repository with default setup enabled for 6 months, the weekly schedule will be disabled to save your GitHub Actions minutes" — and `schedule` is documented `weekly | null`, so a quiet boundary repository reports `configured`, has a real analysis history, and is no longer being analysed. This clause is what entitles the freshness clause below to treat a gap as a failure rather than as a repository nobody pushed to. An organization that enabled monthly scans of inactive repositories fails it while behaving correctly, which is a finding wanting one sentence rather than a defect. | every row | SI-10 |
| analyses[?category=='<CATEGORY>'] | [0].rules_count | gt 0The most recent analysis FOR THIS LANGUAGE ran with at least one rule in it. The category filter is load-bearing rather than tidy: without it this reads position zero of a list that mixes languages, and a green result can come from a run that never touched the code in question. It catches the pathological run — a configured repository whose analysis completed with an empty or failed query pack produces an analysis record, a satisfying `created_at`, `results_count` of zero, and no alerts. `rules_count` is what distinguishes that from a clean scan; `error` and `warning` sit on the same object and are worth reading beside it, and are unasserted because their empty forms are not documented. It counts rules and says nothing about WHICH rules — see the note on why the CWE-family coverage limb is not assertable. | every row | SI-10 |
| analyses[?category=='<CATEGORY>'] | [0].created_at | max_age_days 7The most recent CodeQL analysis for this language on the default branch is no more than seven days old. Seven comes from the `schedule: weekly` field asserted above, not from the once-a-week sentence in the workflow documentation — that sentence is scoped to the default analysis workflow which advanced setup installs and a default-setup repository has no copy of. With the schedule clause green, a wider gap means the scheduled run did not happen. Read the note on cadence before treating seven as sufficient: the indicator's own class-c MUST is shorter than the schedule this clause enforces. | every row | SI-10 |
| alerts-open[?rule.tags==`null`] | count_eq 0Every open alert carries the tag array the CWE clause below reads. This is a guard, not a finding about the code: `tags` is documented "array of string or null", and a `contains()` filter over a null array is the one case that cannot be answered — depending on the evaluator it either raises or quietly drops the row, and in an offender-form `count_eq 0` clause dropping it makes the result GREENER. So the rows with no array are counted here instead of being exempted there. The command's `tool_name=CodeQL` narrowing already removes the likeliest source of untagged rows, third-party SARIF uploaded into the same store; this clause is what makes that a checked fact rather than an assumption. | every row | SI-10 |
| alerts-open[?contains(rule.tags,'external/cwe/cwe-089') || contains(rule.tags,'external/cwe/cwe-078') || contains(rule.tags,'external/cwe/cwe-079')] | count_eq 0No open alert names a sink in the three injection families verified for this recipe — SQL and NoSQL injection (CWE-089), OS command injection (CWE-078) and reflected cross-site scripting (CWE-079). Offender form over a list built to hold offenders, so it reports the rows that fail rather than projecting over the rows that already pass, and it is readable only once the guard above has established that every row has a tag array to search. Two limits are its meaning rather than caveats beside it: the family list is a verified SUBSET of what SI-10 covers rather than a definition of it, and a green result is a statement about paths the ruleset models from sources it treats as untrusted, not about the provider's own list of information inputs. | every row | SI-10 |
Authored opinion, like the commands. Units live in the operator name — max-age-days is days, and nothing here is converted for you.
Map — what it proves
- recipe1
- recipe— an authored recipe collects evidence for this control
- KSI only— a Key Security Indicator reaches it, but no recipe is authored yet
- orphan— no Key Security Indicator reaches it — a person writes it up instead
What else these families can fetch:SI 10/35 →
Outside the boundaryGitHub Enterprise Cloud
The analysis engine, the ruleset it ran and the findings it produced are all held and operated by a third party, so reading them brings the platform into the assessment as an information resource under SA-09 and CA-03 and into the external-system inventory AC-20 covers. The dependency is sharper here than on most recipes because the EVIDENCE ITSELF is a property of someone else's ruleset: what counts as an unvalidated input is decided by queries the provider does not write, version, or necessarily see, and a query pack update can change what a clean result means without anything in the provider's system changing. SI-10 is a class c and class d control, so every reader is running a Moderate or High system, and the impact level a platform's Marketplace listing carries is not necessarily the one those systems need — that is the SA-09 question, it is answered by reading the cited listing, and no value for it is written here because it is a dated fact that changes. This recipe was authored against GitHub Enterprise Cloud; github.com and the data-residency offering are different deployments on different infrastructure.
Notes & assertions
SI-10 asks the provider to check the validity of organization-defined information inputs, and the defining is the half no scanner does. Taint-tracking analysis is genuine telemetry about the other half — a path from a source the ruleset models to a sink it knows is exactly what an input-validation failure looks like in code — but a clean result says "no sink the ruleset knows about, reachable from a source it models" and the control says "the inputs we defined are checked". Those are different sentences, and `scan_scope` names the second list because nothing in this output contains it. THE THREAT MODEL IS THE SHARPEST TRAP ON THIS CONTROL AND IT LOOKS LIKE A SOLVED PROBLEM. `threat_model` is a field in the response with a value of `remote` or `remote_and_local`, so it reads like a setting a provider can simply turn up. GitHub documents that "The default threat model includes remote sources of untrusted data" and that extending it to local sources — "command-line arguments, environment variables, file systems, and databases" — is "currently in public preview and subject to change" and "supported only by analysis for Java/Kotlin and C#". Two consequences follow, and both are findings rather than caveats. On a codebase in any other language, there is no local-source configuration to make: a CLI argument, an environment variable or a row read back out of the database is NOT in the model the scan used, and SI-10's information inputs frequently include exactly those. And where the language does support it, the capability is in public preview, which is a poor foundation for a control statement in a Moderate or High system. Nothing below asserts `remote_and_local`, deliberately — asserting it would fail every provider whose language cannot express it, while implying the ones that can have covered local inputs. WHY THE RULESET-COVERAGE LIMB IS COLLECTED AND NOT ASSERTED, AND WHY THAT IS WHAT KEEPS THIS RECIPE `partial`. The clause an assessment actually wants is "a query for this CWE family was in the run", because that is what makes an empty finding list meaningful. It is not writable from the documented API. `rule.tags` exists only on alerts that exist, so the CWE tags are visible precisely when something was found and invisible in the case where the claim matters. `rules_count` counts rules without naming them. The SARIF response is the closest available and GitHub documents it as "a subset of the analysis data that was uploaded" — a subset cannot establish the absence of a rule, and a recipe that asserted over it would be reading an unspecified sample as a population. What IS writable, and is now asserted, is the coarser half of the same question: that the language was selected at all. The residue — which QUERIES ran within that language — is what keeps this `partial`, and the residue is a property of the documented API rather than of this batch's effort. Two things could close it and neither is in scope here: a documented endpoint listing a run's rules, or the published per-language suite membership read against `query_suite`, which is an inference the cited pages do not license. WHAT THE QUERY SUITE CHANGES ABOUT THE WORD "CLEAN". GitHub documents the `default` suite as "highly precise" with "few false positive" results, and `security-extended` as "all the queries in the default query suite, plus additional queries with slightly lower precision and severity" that "may return a greater number of false positive code scanning results". So a clean result under `default` is a weaker statement than a clean result under `extended` — fewer queries asked fewer questions — and a provider that switched to `extended` and now has open alerts has not regressed. The value is collected and not asserted because SI-10 names no suite; treating `extended` as a requirement would be authoring a preference as a control. A CADENCE GAP WORTH STATING PLAINLY, BECAUSE IT IS THE PLATFORM FAILING THE INDICATOR RATHER THAN THE PROVIDER. The freshness clause enforces seven days because that is what `schedule: weekly` means. KSI-CNA-MAT's own class-c floor is the VDR-TFR-MVX MUST — verify and validate the status of machine-based information resources at least once every three days — which is tighter, and SI-10 is a class c and class d control, so this reaches every reader. On an actively developed repository the gap closes by itself, because default setup also scans on pushes and pull requests; on a boundary repository that is quiet, the weekly schedule is the only thing running and the schedule clause is the only reason its silence is visible at all. For class d the binding MUST is LOOSER rather than tighter — read it off `classClocks[].tightestMust`, because the tightest class-d clock is a SHOULD — so this is a class-c fact and not a monotonic one. A provider needing to close it moves to advanced setup and its own schedule, which is a different recipe against a different endpoint. The default-branch limit applies here as it does to the sibling recipe on this platform: alert status reflects the default branch, the organization-scoped alerts endpoint takes no `ref` filter, and the analyses command pins `ref` to the default branch for the same reason. This is a default-branch statement about a repository, not a repository-wide one. KSI-PIY-RSD also reaches this control and is deliberately NOT claimed. That indicator asks whether the effectiveness of building security into the SDLC is persistently reviewed, and a scan record is an input to such a review rather than the review itself — the same reason the secret-scanning recipe declined the rotation limb of its adjacent indicator. KSI-CNA-MAT is claimed because an injection sink reachable from untrusted input is attack surface in the indicator's own terms — the dataset's own glossary counts code among machine-based information resources — and a recurring analysis over a named repository set is the persistent review it asks for.
Scanned population
Two lists, both held OUTSIDE the platform, and this control needs both. First, the repositories inside the authorization boundary from the provider's CM-08 component inventory — a repository never attached to a configuration and with scanning off in its own settings is absent from every response here rather than false in any of them. The enumeration is narrowed to `status=attached,enforced` on purpose: the documented default is `all`, which returns `failed`, `detached` and `removed` rows as well, and reconciling those against the boundary list reads as coverage for repositories the scanner never reached — the anti-vacuity mechanism over-counting in the one direction that hides the trap. The dropped rows are not ignored; a `failed` attachment is what the sibling recipe `static-analysis-coverage-and-flaw-disposition` asserts on directly. Second, and specific to this control, SI-10's organization-defined information inputs: the interfaces the provider's own design documentation says accept untrusted data — request bodies and query parameters, file uploads, message-queue payloads, webhook receivers, CLI arguments, environment and configuration read at start-up, and rows read back from a database populated by users. That list is authored by a human and it is what the scan's coverage has to be reconciled against, because a taint-tracking query finds a path from a source it MODELS to a sink it knows; an input the model does not treat as a source produces no finding no matter how unvalidated it is. The `threat_model` and `languages` fields returned by the third command are the platform's half of that reconciliation and are the reason this recipe collects them — that command is not in `enumerated_by` because it enumerates no population; it describes one repository.
- configurations
- configuration-repositories
References
- GitHub REST: code scanning — GET /orgs/{org}/code-scanning/alerts (filters tool_name, tool_guid, state open | closed | dismissed | fixed, severity critical | high | medium | low | warning | note | error, sort created | updated, direction, assignees; no ref filter at organization scope), GET /repos/{owner}/{repo}/code-scanning/alerts (adds ref and pr), GET /repos/{owner}/{repo}/code-scanning/analyses (filters tool_name, tool_guid, ref, sarif_id, pr; sort created only, direction desc by default) returning ref, commit_sha, analysis_key, environment, category, error, created_at, results_count, rules_count, id, url, sarif_id, tool, deletable, warning; GET /repos/{owner}/{repo}/code-scanning/default-setup returning state configured | not-configured, languages, runner_type standard | labeled | null, runner_label, query_suite default | extended, threat_model remote | remote_and_local, updated_at, schedule weekly | null; alert rule sub-object id, name, severity none | note | warning | error, security_severity_level low | medium | high | critical, description, full_description, tags declared "array of string or null", help, help_uri, and dismissed_reason false positive | won't fix | used in tests | mitigated | null with dismissed_by, dismissed_at and dismissed_comment (nullable, max 280 characters); alerts and analyses need the security_events scope, default setup needs repo https://docs.github.com/en/rest/code-scanning/code-scanning
- GitHub REST: code security configurations — code_scanning_default_setup and code_scanning_delegated_alert_dismissal each documented as enabled | disabled | not_set, code_scanning_default_setup_options carrying runner_type standard | labeled | not_set and runner_label; the response `target_type` is global | organization | enterprise while the LIST endpoint's own target_type parameter is documented "Default: all"; the repositories endpoint takes "A comma-separated list of statuses. If specified, only repositories with these attachment statuses will be returned. Can be: all, attached, attaching, detached, removed, enforced, failed, updating, removed_by_enterprise. Default: `all`"; both organization endpoints need read:org and an organization administrator or security manager https://docs.github.com/en/rest/code-security/configurations
- GitHub: configuring default setup for code scanning — the schedule this recipe's freshness clause rests on, and the documented reason it stops: "If no pushes and pull requests have occurred in a repository with default setup enabled for 6 months, the weekly schedule will be disabled to save your GitHub Actions minutes", and "Organization owners can enable monthly scans of inactive repositories" https://docs.github.com/en/code-security/code-scanning/enabling-code-scanning/configuring-default-setup-for-code-scanning
- GitHub: code scanning workflow configuration options — "The default threat model includes remote sources of untrusted data", extended to local sources "(for example: command-line arguments, environment variables, file systems, and databases) by specifying threat-models: local"; the feature is "currently in public preview and subject to change" and "supported only by analysis for Java/Kotlin and C#"; security-extended is "Queries from the default suite, plus lower severity and precision queries" and security-and-quality adds maintainability and reliability queries; "Use category to distinguish between multiple analyses for the same tool and commit, but performed on different languages or different parts of the code"; and the once-a-week sentence, which is scoped to the default analysis WORKFLOW — advanced setup — not to default setup https://docs.github.com/en/code-security/reference/code-scanning/workflow-configuration-options
- GitHub: editing your configuration of default setup — "(Public preview) Optionally, in the 'Threat model' row of the 'Scan settings' section, select Remote and local sources. This option is only available for repositories with code in a supported language: Java/Kotlin and C#", and the query suite is chosen in the same Scan settings section https://docs.github.com/en/code-security/how-tos/find-and-fix-code-vulnerabilities/manage-your-configuration/edit-default-setup
- GitHub: CodeQL query suites — the queries in the default suite "are highly precise and return few false positive code scanning results"; security-extended "consists of all the queries in the default query suite, plus additional queries with slightly lower precision and severity" and "may return a greater number of false positive code scanning results"; both are available to default setup and a custom suite requires advanced setup https://docs.github.com/en/code-security/concepts/code-scanning/codeql/codeql-query-suites
- CodeQL: metadata for CodeQL queries — @tags carries the query's categories, @precision "Indicates the percentage of query results that are true positives" with values low | medium | high | very-high, @problem.severity "Defines the level of severity of any alerts generated by a non-security query", and @security-severity "Defines the level of severity, between 0.0 and 10.0, for queries with @tags security" https://codeql.github.com/docs/writing-codeql-queries/metadata-for-codeql-queries/
- CodeQL query help: js/sql-injection — CWE-089, CWE-090 and CWE-943, carrying the tags security, external/cwe/cwe-089, external/cwe/cwe-090 and external/cwe/cwe-943; a database query "built from user-provided data without sufficient sanitization" https://codeql.github.com/codeql-query-help/javascript/js-sql-injection/
- CodeQL query help: js/command-line-injection — CWE-078 and CWE-088, carrying the tags correctness, security, external/cwe/cwe-078 and external/cwe/cwe-088; "Code that passes untrusted user input directly to child_process.exec or similar APIs that execute shell commands" https://codeql.github.com/codeql-query-help/javascript/js-command-line-injection/
- CodeQL query help: js/reflected-xss — CWE-079 and CWE-116, carrying the tags security, external/cwe/cwe-079 and external/cwe/cwe-116; "Directly writing user input (for example, an HTTP request parameter) to an HTTP response without properly sanitizing the input first" https://codeql.github.com/codeql-query-help/javascript/js-reflected-xss/
- GitHub REST: get a code scanning analysis — supports the application/sarif+json custom media type, which returns "a subset of the analysis data that was uploaded" formatted as SARIF 2.1.0 plus github/alertNumber and github/alertUrl; the default media type returns the analysis summary rather than the SARIF payload https://docs.github.com/en/rest/code-scanning/code-scanning#get-a-code-scanning-analysis-for-a-repository
- FedRAMP Marketplace: GitHub Enterprise Cloud — the listing to re-read rather than quote, and the place to check the impact level against the class c and class d systems SI-10 applies to; a certification status is a dated fact about a product, not about your deployment https://www.fedramp.gov/marketplace/products/FR1812058188/
This pipeline mapping is authored opinion (overlay v0.8.0), versioned separately from the dataset and written against ruleset 2026.07.14.01. The upstream FedRAMP dataset names none of these tools.
The Cloud Native Architecture run (7)
- automatable
- partial — needs judgement
- narrative — no API proves this
Every authored recipe filed under CNA, in the order the plan works them. The mark says how much of the evidence the command produces on its own.
- partialAWS Config compliance results proving the network boundary is controlled — no security group exposes SSH to the internet, groups open to 0.0.0.0/0 only allow authorized ports, and every VPC's default security group denies all trafficcontinuousconfig-network-boundary-protectionAWS Config · Amazon VPC · Amazon EC2
- partialEvery route in or out of the boundary, named and counted — internet gateways, NAT gateways, VPC endpoints and Site-to-Site VPN tunnels — alongside what each boundary device does with traffic that matched no rule: the network ACL entries, the closed default security group, subnets that hand out public IPs, and the firewall policy's stateless and stateful default actionsweeklyboundary-access-points-and-default-denyAmazon VPC · Amazon EC2 · AWS Network Firewall · AWS Config
- partialThe denial-of-service defences that are actually attached to the internet-facing resources — the Shield Advanced subscription and the list of resources it protects, the web ACL's rate-based rules and their limits, whether web ACL logging is on — plus what those defences observed: the attacks Shield recorded over the period and the CloudWatch detection and block counts underneath themdailyddos-protection-and-rate-limitingAWS Shield Advanced · AWS WAF · Amazon CloudWatch · AWS Config
- partialWhether malware scanning is switched on for compute and for the buckets that accept uploads, plus the scan-by-scan record of what was actually examined and what came back INFECTEDweeklymalicious-code-protectionAmazon GuardDuty · Amazon EC2 · Amazon S3 · AWS Config
- partialThe machine-generated inventory of every plane on which one part of the system reaches another — VPC peering connections, Transit Gateway attachments, the interface and gateway endpoints this account consumes, the endpoint connections other accounts have made INTO your endpoint service, and the security-group rules that name another group rather than a CIDR — each narrowed to the states that are actually livecontinuousinternal-connection-inventory-and-authorizationAmazon VPC · AWS Transit Gateway · AWS PrivateLink
- partialWhich taint-tracking ruleset actually ran over this repository — the query suite, the languages selected, and the threat model that decides what counts as an untrusted source — together with whether the recurring scan is still scheduled, when it last ran per analysed language, and how many rules were in the run; and then the open findings in the injection families SI-10 is about, identified by the CWE tags the queries carry. The ruleset and the freshness are the load-bearing half: a finding names a sink that exists, but only the run record says the absence of findings means anything at all.you are herecontinuousinput-validation-taint-analysis-coverageGitHub code scanning · GitHub CodeQL
- partialWhether the queries that find information disclosure through an error message or a stack trace ran over this part of the boundary — which languages were selected, whether the recurring scan is still scheduled and when it last completed — and then the open findings those queries produced, identified by the CWE tags the queries carry rather than by their names. The run record is the load-bearing half here as it is on every scanning recipe: a finding names a leak that exists, and only the record of a scan having run over a selected language makes the absence of findings a statement about anything.continuouserror-handling-information-exposure-scanningGitHub code scanning · GitHub CodeQL · GitHub code security configurations