Authentication
The GitHub shim authenticates the job runtime token (the credential a workflow step receives asGITHUB_TOKEN): Bearer <token>, Octokit’s
token <token>, or Basic x-access-token:<token>. The token is resolved
through the job → run → submission chain, so the repository and run come from
the credential, never from the request body. A token for another repository is
rejected with 403.
The native run API accepts the same job runtime token — it must belong to the
{run_id} in the path — or the system token. Native errors keep the usual
{ "error": ... } envelope; the GitHub shim answers with GitHub’s
{ "message": ..., "documentation_url": ... } shape.
Upload limits
A payload over a limit is refused with
413; malformed base64, gzip, JSON or
a SARIF version other than 2.1.0 is refused with 400.
GitHub payload
The shim accepts the payloadupload-sarif sends: sarif is
base64(gzip(SARIF)), commit_sha (the legacy endpoint’s name) or
commit_oid (the current endpoint’s name), ref, and optionally tool_name,
tool_names, checkout_uri, started_at, analysis_key, environment,
base_ref and base_sha.
A successful upload answers 202:
{"processing_status":"complete","analyses_url":…,"sarif_id":…,"errors":[]}.
Parsing is synchronous, so an analysis is complete by the time the first
status read lands. Unknown ids and ids belonging to another repository both
answer 404.
Native payload
POST /api/v1/runs/{run_id}/sarif accepts either the SARIF document itself:
sarif field is the document object or a
base64(gzip(SARIF)) string. Optional wrapper fields: commit_sha, ref,
tool_name, tool_names, checkout_uri, started_at, analysis_key,
environment. Missing commit_sha/ref default to the run’s own submission.
A Content-Encoding: gzip body is decompressed before parsing.
The response is 202:
GET /api/v1/sarif/{analysis_id} returns the analysis metadata and the
findings:
Idempotency
An upload is deduplicated on a content fingerprint over the repository, commit, ref, tool name and the sorted finding fingerprints —partialFingerprints
first, then fingerprints, then a value derived from the location and
message. Re-uploading the same findings for the same commit reuses the stored
analysis (the same id/analysis_id), even when the raw bytes differ in
formatting or result order. Findings inside one analysis are deduplicated on
their fingerprint, so a producer that lists the same issue twice stores it
once.
Storage
Raw SARIF is gzip-compressed in<state-dir>/sarif/<analysis-id>.sarif.gz.
Metadata lives in the control database (sarif_analyses) and normalized
findings in sarif_findings, so list/read work on every node sharing the
database; the raw-document read is served by the node whose state directory
holds the file.
Analysis-key derivation
github/codeql-action derives its analysis_key from
GET /repos/{owner}/{repo}/actions/runs/{run_id} when the workflow does not
supply one. The engine answers that read from the caller’s job token (the
segment the action sends is NaN, because Octokit coerces the engine’s UUID
run id) and returns the run’s repository-relative workflow path with
workflow_url: null, which is the action’s documented fallback — so it does
not make a second workflow request. Only the caller’s own run is served.