Skip to content

ci: upload security SARIF without CodeQL action#66

Merged
haasonsaas merged 1 commit intomainfrom
codex/codeql-sarif-api
Apr 30, 2026
Merged

ci: upload security SARIF without CodeQL action#66
haasonsaas merged 1 commit intomainfrom
codex/codeql-sarif-api

Conversation

@haasonsaas
Copy link
Copy Markdown
Contributor

Summary

  • replace github/codeql-action/upload-sarif in the security scan job with a direct Code Scanning SARIF API uploader
  • preserve best-effort uploads via continue-on-error
  • tag gosec and Trivy uploads with stable categories

Verification

  • python3 -m py_compile scripts/upload-sarif-to-code-scanning.py
  • python3 scripts/upload-sarif-to-code-scanning.py --help
  • mocked upload smoke test for the Code Scanning API request path
  • ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml")'\n- actionlint .github/workflows/ci.yml\n- git diff --check\n\nRefs codeql-guard: CodeQL workflow drift detected .github#32

@cursor
Copy link
Copy Markdown

cursor Bot commented Apr 30, 2026

PR Summary

Medium Risk
Changes CI security-reporting behavior by replacing a maintained GitHub Action with a custom API uploader, which could affect whether findings appear in Code Scanning. Runtime risk is limited to CI and guarded by continue-on-error.

Overview
Updates the security-scan GitHub Actions job to stop using github/codeql-action/upload-sarif and instead upload gosec and trivy SARIF results via a new scripts/upload-sarif-to-code-scanning.py script, while keeping best-effort uploads with continue-on-error and stable --category tags.

Adds the Python uploader that gzips+base64 encodes SARIF, posts to /code-scanning/sarifs using GITHUB_TOKEN, handles merge_group refs, and downgrades common “Code Security not enabled” 403s to a warning rather than failing the job.

Reviewed by Cursor Bugbot for commit 2fec559. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Wrong checkout_uri prevents SARIF path mapping
    • The script now sends checkout_uri as a file:// workspace URI so GitHub can relativize absolute SARIF paths correctly.
  • ✅ Fixed: No-op conditional makes ref validation ineffective
    • The ref helper now rejects unsupported refs instead of returning them unchanged, so the validation check is effective.
Preview (2fec559bb0)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -132,10 +132,10 @@
         run: gosec -fmt sarif -out gosec.sarif ./...
 
       - name: Upload gosec results
-        uses: github/codeql-action/upload-sarif@v4
         continue-on-error: true
-        with:
-          sarif_file: gosec.sarif
+        env:
+          GITHUB_TOKEN: ${{ github.token }}
+        run: python3 scripts/upload-sarif-to-code-scanning.py --sarif-file gosec.sarif --category gosec
 
       - name: Run Trivy vulnerability scanner
         uses: aquasecurity/trivy-action@master
@@ -146,10 +146,10 @@
           output: 'trivy-results.sarif'
 
       - name: Upload Trivy results
-        uses: github/codeql-action/upload-sarif@v4
         continue-on-error: true
-        with:
-          sarif_file: 'trivy-results.sarif'
+        env:
+          GITHUB_TOKEN: ${{ github.token }}
+        run: python3 scripts/upload-sarif-to-code-scanning.py --sarif-file trivy-results.sarif --category trivy
 
   build:
     name: Build and Test Docker Images

diff --git a/scripts/upload-sarif-to-code-scanning.py b/scripts/upload-sarif-to-code-scanning.py
new file mode 100644
--- /dev/null
+++ b/scripts/upload-sarif-to-code-scanning.py
@@ -1,0 +1,84 @@
+#!/usr/bin/env python3
+"""Upload a SARIF file to GitHub Code Scanning without the CodeQL action."""
+
+from __future__ import annotations
+
+import argparse
+import base64
+import gzip
+import json
+import os
+from pathlib import Path
+import sys
+import urllib.error
+import urllib.request
+
+
+def code_scanning_ref() -> str:
+    ref = os.environ["GITHUB_REF"]
+    if os.environ.get("GITHUB_EVENT_NAME") == "merge_group":
+        with open(os.environ["GITHUB_EVENT_PATH"], encoding="utf-8") as event_file:
+            event = json.load(event_file)
+        base_ref = event.get("merge_group", {}).get("base_ref", "")
+        if base_ref.startswith("refs/heads/"):
+            return base_ref
+        if base_ref:
+            return f"refs/heads/{base_ref}"
+    if ref.startswith(("refs/heads/", "refs/pull/")):
+        return ref
+    raise ValueError(f"unsupported GITHUB_REF for Code Scanning SARIF upload: {ref}")
+
+
+def parse_args() -> argparse.Namespace:
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument("--sarif-file", required=True, type=Path)
+    parser.add_argument("--category")
+    return parser.parse_args()
+
+
+def main() -> int:
+    args = parse_args()
+    sarif_payload = base64.b64encode(gzip.compress(args.sarif_file.read_bytes())).decode(
+        "ascii"
+    )
+
+    body = {
+        "commit_sha": os.environ["GITHUB_SHA"],
+        "ref": code_scanning_ref(),
+        "sarif": sarif_payload,
+        "checkout_uri": f"file://{os.environ['GITHUB_WORKSPACE']}",
+    }
+    if args.category:
+        body["category"] = args.category
+
+    request = urllib.request.Request(
+        f"{os.environ['GITHUB_API_URL']}/repos/{os.environ['GITHUB_REPOSITORY']}/code-scanning/sarifs",
+        data=json.dumps(body).encode("utf-8"),
+        method="POST",
+        headers={
+            "Accept": "application/vnd.github+json",
+            "Authorization": f"Bearer {os.environ['GITHUB_TOKEN']}",
+            "Content-Type": "application/json",
+            "X-GitHub-Api-Version": "2022-11-28",
+        },
+    )
+    try:
+        with urllib.request.urlopen(request) as response:
+            print(response.read().decode("utf-8"))
+    except urllib.error.HTTPError as error:
+        response_body = error.read().decode("utf-8")
+        response_body_lower = response_body.lower()
+        if error.code == 403 and (
+            "advanced security must be enabled" in response_body_lower
+            or "code scanning is not enabled" in response_body_lower
+            or "code security must be enabled" in response_body_lower
+        ):
+            print("::warning::Code Security is not enabled; skipping SARIF upload.")
+            return 0
+        sys.stderr.write(response_body)
+        raise
+    return 0
+
+
+if __name__ == "__main__":
+    raise SystemExit(main())

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit c114212. Configure here.

Comment thread scripts/upload-sarif-to-code-scanning.py Outdated
Comment thread scripts/upload-sarif-to-code-scanning.py Outdated
@haasonsaas haasonsaas force-pushed the codex/codeql-sarif-api branch from c114212 to 2fec559 Compare April 30, 2026 14:11
@haasonsaas haasonsaas merged commit c32f55d into main Apr 30, 2026
7 checks passed
@haasonsaas haasonsaas deleted the codex/codeql-sarif-api branch April 30, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant