Skip to content

Restrict GITHUB_TOKEN permissions in build workflows - #499

Merged
dannystaple merged 1 commit into
masterfrom
fix/codeql-workflow-permissions
Sep 19, 2026
Merged

dannystaple merged 1 commit into
masterfrom
fix/codeql-workflow-permissions

Conversation

@dannystaple

Copy link
Copy Markdown
Member

Fixes CodeQL actions/missing-workflow-permissions alerts 1, 2, 3, 4, 5 and 18.

Verification: actionlint clean; on_pr_test.yaml exercises the same caller→callee nesting so this PR's own checks validate it. The push workflow only runs on master, so I'll watch its run after merge.

🤖 Generated with Claude Code

Add top-level contents: read, and grant packages: write on the jobs that
call the reusable build/staging workflows (a callee cannot exceed what its
calling job grants, which is what broke the earlier attempt in #488).
Callee jobs now state contents: read explicitly.

Addresses CodeQL actions/missing-workflow-permissions alerts 1-5 and 18.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Max errors Warnings Elapsed time
✅ ACTION actionlint 7 0 0 0.13s
⚠️ ACTION zizmor 7 1 0 0.34s
✅ BASH bash-exec 2 0 0 0.01s
✅ BASH shellcheck 2 0 0 0.18s
⚠️ BASH shfmt 2 1 0 0.02s
⚠️ C cppcheck 8 8 0 0.05s
⚠️ CPP cppcheck 8 8 0 0.06s
✅ JSON npm-package-json-lint yes no no 0.58s
✅ JSON v8r 17 0 0 9.79s
✅ REPOSITORY betterleaks yes no no 1.26s
✅ REPOSITORY git_diff yes no no 0.58s
✅ REPOSITORY grype yes no no 55.86s
✅ REPOSITORY osv-scanner yes no no 1.3s
✅ REPOSITORY secretlint yes no no 10.89s
✅ REPOSITORY syft yes no no 2.57s
✅ REPOSITORY trivy-sbom yes no no 1.72s
✅ REPOSITORY trufflehog yes no no 5.97s
✅ TYPESCRIPT ts-standard 3 0 0 5.15s
✅ XML xmllint 1 0 0 7.54s
✅ YAML v8r 15 0 0 8.46s

Detailed Issues

⚠️ C / cppcheck - 8 errors
Checking assets/2013-11-14-explorer-wall-avoider-kit/alternative_demo/DistanceSensor.h ...
assets/2013-11-14-explorer-wall-avoider-kit/alternative_demo/DistanceSensor.h:3:1: error: Code 'classSR04{' is invalid C code. [syntaxError]
class SR04 {
^
1/8 files checked 12% done
Checking assets/2013-11-14-explorer-wall-avoider-kit/alternative_demo/Motors.h ...
assets/2013-11-14-explorer-wall-avoider-kit/alternative_demo/Motors.h:3:1: error: Code 'classMotor{' is invalid C code. [syntaxError]
class Motor {
^
2/8 files checked 19% done
Checking assets/2013-11-14-explorer-wall-avoider-kit/demo_sketch/DistanceSensor.h ...
assets/2013-11-14-explorer-wall-avoider-kit/demo_sketch/DistanceSensor.h:3:1: error: Code 'classSR04{' is invalid C code. [syntaxError]
class SR04 {
^
3/8 files checked 31% done
Checking assets/2013-11-14-explorer-wall-avoider-kit/demo_sketch/TurtleMotors.h ...
assets/2013-11-14-explorer-wall-avoider-kit/demo_sketch/TurtleMotors.h:3:1: error: Code 'classMotor{' is invalid C code. [syntaxError]
class Motor {
^
4/8 files checked 49% done
Checking galleries/2013-11-14-explorer-wall-avoider-kit/alternative_demo/DistanceSensor.h ...
galleries/2013-11-14-explorer-wall-avoider-kit/alternative_demo/DistanceSensor.h:3:1: error: Code 'classSR04{' is invalid C code. [syntaxError]
class SR04 {
^
5/8 files checked 62% done
Checking galleries/2013-11-14-explorer-wall-avoider-kit/alternative_demo/Motors.h ...
galleries/2013-11-14-explorer-wall-avoider-kit/alternative_demo/Motors.h:3:1: error: Code 'classMotor{' is invalid C code. [syntaxError]
class Motor {
^
6/8 files checked 69% done
Checking galleries/2013-11-14-explorer-wall-avoider-kit/demo_sketch/DistanceSensor.h ...
galleries/2013-11-14-explorer-wall-avoider-kit/demo_sketch/DistanceSensor.h:3:1: error: Code 'classSR04{' is invalid C code. [syntaxError]
class SR04 {
^
7/8 files checked 81% done
Checking galleries/2013-11-14-explorer-wall-avoider-kit/demo_sketch/TurtleMotors.h ...
galleries/2013-11-14-explorer-wall-avoider-kit/demo_sketch/TurtleMotors.h:3:1: error: Code 'classMotor{' is invalid C code. [syntaxError]
class Motor {
^
8/8 files checked 100% done
⚠️ CPP / cppcheck - 8 errors
Checking assets/2013-11-14-explorer-wall-avoider-kit/alternative_demo/DistanceSensor.h ...
assets/2013-11-14-explorer-wall-avoider-kit/alternative_demo/DistanceSensor.h:3:1: error: Code 'classSR04{' is invalid C code. [syntaxError]
class SR04 {
^
1/8 files checked 12% done
Checking assets/2013-11-14-explorer-wall-avoider-kit/alternative_demo/Motors.h ...
assets/2013-11-14-explorer-wall-avoider-kit/alternative_demo/Motors.h:3:1: error: Code 'classMotor{' is invalid C code. [syntaxError]
class Motor {
^
2/8 files checked 19% done
Checking assets/2013-11-14-explorer-wall-avoider-kit/demo_sketch/DistanceSensor.h ...
assets/2013-11-14-explorer-wall-avoider-kit/demo_sketch/DistanceSensor.h:3:1: error: Code 'classSR04{' is invalid C code. [syntaxError]
class SR04 {
^
3/8 files checked 31% done
Checking assets/2013-11-14-explorer-wall-avoider-kit/demo_sketch/TurtleMotors.h ...
assets/2013-11-14-explorer-wall-avoider-kit/demo_sketch/TurtleMotors.h:3:1: error: Code 'classMotor{' is invalid C code. [syntaxError]
class Motor {
^
4/8 files checked 49% done
Checking galleries/2013-11-14-explorer-wall-avoider-kit/alternative_demo/DistanceSensor.h ...
galleries/2013-11-14-explorer-wall-avoider-kit/alternative_demo/DistanceSensor.h:3:1: error: Code 'classSR04{' is invalid C code. [syntaxError]
class SR04 {
^
5/8 files checked 62% done
Checking galleries/2013-11-14-explorer-wall-avoider-kit/alternative_demo/Motors.h ...
galleries/2013-11-14-explorer-wall-avoider-kit/alternative_demo/Motors.h:3:1: error: Code 'classMotor{' is invalid C code. [syntaxError]
class Motor {
^
6/8 files checked 69% done
Checking galleries/2013-11-14-explorer-wall-avoider-kit/demo_sketch/DistanceSensor.h ...
galleries/2013-11-14-explorer-wall-avoider-kit/demo_sketch/DistanceSensor.h:3:1: error: Code 'classSR04{' is invalid C code. [syntaxError]
class SR04 {
^
7/8 files checked 81% done
Checking galleries/2013-11-14-explorer-wall-avoider-kit/demo_sketch/TurtleMotors.h ...
galleries/2013-11-14-explorer-wall-avoider-kit/demo_sketch/TurtleMotors.h:3:1: error: Code 'classMotor{' is invalid C code. [syntaxError]
class Motor {
^
8/8 files checked 100% done
⚠️ BASH / shfmt - 1 error
diff .github/scripts/validate-local-build.sh.orig .github/scripts/validate-local-build.sh
--- .github/scripts/validate-local-build.sh.orig
+++ .github/scripts/validate-local-build.sh
@@ -30,9 +30,9 @@
 echo ""
 echo "=== Step 1: Checking http_serve is running ==="
 if ! docker ps --format '{{.Names}}' | grep -q "^${HTTP_SERVE_CONTAINER}$"; then
-  echo "ERROR: ${HTTP_SERVE_CONTAINER} is not running."
-  echo "Start it with: docker compose --profile manual up -d http_serve"
-  exit 1
+    echo "ERROR: ${HTTP_SERVE_CONTAINER} is not running."
+    echo "Start it with: docker compose --profile manual up -d http_serve"
+    exit 1
 fi
 
 # ─── Step 2: Quick HTTP smoke check from host ─────────────────────────────────
@@ -39,17 +39,17 @@
 echo ""
 echo "=== Step 2: HTTP smoke checks (host -> port ${HOST_PORT}) ==="
 for path in "/" "/construction_guide.html" "/tags/arduino/"; do
-  status=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${HOST_PORT}${path}")
-  if [[ "$status" == "200" ]]; then
-    echo "  OK  ${path} -> ${status}"
-  else
-    echo "  FAIL ${path} -> ${status}"
-    SMOKE_FAILED=1
-  fi
+    status=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${HOST_PORT}${path}")
+    if [[ "$status" == "200" ]]; then
+        echo "  OK  ${path} -> ${status}"
+    else
+        echo "  FAIL ${path} -> ${status}"
+        SMOKE_FAILED=1
+    fi
 done
 if [[ -n "${SMOKE_FAILED:-}" ]]; then
-  echo "ERROR: Smoke checks failed."
-  exit 1
+    echo "ERROR: Smoke checks failed."
+    exit 1
 fi
 
 # ─── Step 3: Verify AVIF images are generated ────────────────────────────────
@@ -62,8 +62,8 @@
 echo "  Post body WebP: ${webp_count}"
 echo "  Thumbnail AVIF: ${thumb_avif}"
 if [[ "$avif_count" -eq 0 ]]; then
-  echo "ERROR: No AVIF images found in _site/assets/images. Was the build run?"
-  exit 1
+    echo "ERROR: No AVIF images found in _site/assets/images. Was the build run?"
+    exit 1
 fi
 
 # ─── Step 4: BDD tests ─────────────────────────────────────────────────────
@@ -71,14 +71,14 @@
 echo "=== Step 4: BDD tests (via Docker, network: ${DOCKER_NETWORK}) ==="
 
 docker run --rm \
-  --network "${DOCKER_NETWORK}" \
-  -e BASE_URL="${BASE_URL}" \
-  -v "${PROJECT_ROOT}/tests:/app/src/tests" \
-  -v "${PROJECT_ROOT}/package.json:/app/src/package.json" \
-  -v "${PROJECT_ROOT}/package-lock.json:/app/src/package-lock.json" \
-  -v "${PROJECT_ROOT}/cucumber.js:/app/src/cucumber.js" \
-  "${TEST_IMAGE}" \
-  npm run test:bdd
+    --network "${DOCKER_NETWORK}" \
+    -e BASE_URL="${BASE_URL}" \
+    -v "${PROJECT_ROOT}/tests:/app/src/tests" \
+    -v "${PROJECT_ROOT}/package.json:/app/src/package.json" \
+    -v "${PROJECT_ROOT}/package-lock.json:/app/src/package-lock.json" \
+    -v "${PROJECT_ROOT}/cucumber.js:/app/src/cucumber.js" \
+    "${TEST_IMAGE}" \
+    npm run test:bdd
 
 echo ""
 echo "=== Validation complete ==="
⚠️ ACTION / zizmor - 1 error
INFO zizmor: 🌈 zizmor v1.25.0
 WARN audit:audit{input=Workflow(file://.github/workflows/on_call_build_site.yaml)}: zizmor::audit::unpinned_uses: failed to look up commit for docker/setup-buildx-action@v4.3.0: couldn't list branches for docker/setup-buildx-action
fatal: no audit was performed
'artipacked' audit failed on file://.github/workflows/on_call_build_site.yaml

Caused by:
    0: error in 'artipacked' audit
    1: couldn't list tags for actions/checkout
    2: request error while accessing GitHub API
    3: HTTP status client error (401 Unauthorized) for url (https://github.com/actions/checkout.git/git-upload-pack)


[ACTION_ZIZMOR_ERROR_GITHUB_API_UNREACHABLE] Zizmor could not access a repository referenced by a `uses:` clause via the GitHub API (missing token, insufficient scope, or cross-repo private access).
To allow zizmor to authenticate with GITHUB_TOKEN (or a PAT with `Contents: read-only`), whitelist the variable in your .mega-linter.yml:
ACTION_ZIZMOR_UNSECURED_ENV_VARIABLES:
  - GITHUB_TOKEN
If the referenced workflow is in a private repo outside the current one, provide a PAT with cross-repo access instead of the default GITHUB_TOKEN, or run zizmor in offline mode.

Notices

⚠️ Your configuration references items that have been removed from MegaLinter and are ignored: REPOSITORY_KICS. See Removed linters to find their replacements.

See detailed reports in MegaLinter artifacts

You could have the same capabilities but better runtime performances if you use a MegaLinter flavor:

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@10.1.0 --custom-flavor-setup --custom-flavor-linters ACTION_ACTIONLINT,ACTION_ZIZMOR,BASH_EXEC,BASH_SHELLCHECK,BASH_SHFMT,C_CPPCHECK,CPP_CPPCHECK,JSON_V8R,JSON_NPM_PACKAGE_JSON_LINT,REPOSITORY_GIT_DIFF,REPOSITORY_BETTERLEAKS,REPOSITORY_GRYPE,REPOSITORY_OSV_SCANNER,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,TYPESCRIPT_STANDARD,XML_XMLLINT,YAML_V8R

MegaLinter is provided by OX Security
Show us your support by starring ⭐ the repository

@github-actions

Copy link
Copy Markdown
Contributor

🐳 Docker Base Image Available

A new base Docker image has been built and pushed for this PR:

Image: ghcr.io/orionrobots/orionrobots-site.base:499

How to use this image:

# Pull the image
docker pull ghcr.io/orionrobots/orionrobots-site.base:499

# Run with the image
docker run -it ghcr.io/orionrobots/orionrobots-site.base:499 bash

For local development:

You can use this image as a base for testing changes without rebuilding dependencies.

This comment is automatically updated when the base image is rebuilt.

@dannystaple
dannystaple merged commit 44b6ef9 into master Sep 19, 2026
10 checks passed
@dannystaple
dannystaple deleted the fix/codeql-workflow-permissions branch September 19, 2026 13:17
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