From 74f704d003cf86018783eb111adb6827cf863c73 Mon Sep 17 00:00:00 2001
From: aksops
Date: Fri, 1 May 2026 10:42:27 +0000
Subject: [PATCH 1/2] ci(scorecard): add OpenSSF Scorecard workflow + README
badges
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds .github/workflows/scorecard.yml — runs the OpenSSF Scorecard
supply-chain check on push to main, weekly cron, and on
branch_protection_rule changes. Results land in two places:
- GitHub code-scanning (/security/code-scanning) via SARIF upload
- Public Scorecard registry (api.scorecard.dev) via OIDC publish so
the README badge resolves to a live score
All third-party actions are pinned to commit SHAs:
- actions/checkout@v4
- ossf/scorecard-action@v2.4.3
- actions/upload-artifact@v7.0.1
- github/codeql-action/upload-sarif@v4.35.2
README: add the Scorecard badge to the badge row, plus an HTML
comment with the one-time steps to register the project at
bestpractices.dev and append the Best Practices badge once a
PROJECT_ID has been issued (the badge URL is invalid until the
project is registered, so it's documented inline rather than
shipped broken).
Co-Authored-By: Claude Opus 4.7 (1M context)
---
.github/workflows/scorecard.yml | 74 +++++++++++++++++++++++++++++++++
README.md | 22 ++++++++++
2 files changed, 96 insertions(+)
create mode 100644 .github/workflows/scorecard.yml
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
new file mode 100644
index 0000000..28a9efc
--- /dev/null
+++ b/.github/workflows/scorecard.yml
@@ -0,0 +1,74 @@
+name: OpenSSF Scorecard
+
+# Runs the OpenSSF Scorecard supply-chain check on every push to main
+# and weekly. Results are uploaded to GitHub's code-scanning surface
+# (visible at /security/code-scanning) AND published to the public
+# Scorecard registry at api.scorecard.dev so the README badge shows
+# the live score.
+#
+# Required repo settings:
+# - Settings → Actions → General → Workflow permissions: at least
+# "Read repository contents and packages permissions" (default).
+# - Settings → Code security → Code scanning: enabled (so SARIF
+# uploads land somewhere).
+# - The workflow grants `id-token: write` so the action can mint an
+# OIDC token signed by GitHub and use it as proof-of-identity when
+# pushing results to the Scorecard API. No long-lived secret needed.
+
+on:
+ branch_protection_rule:
+ push:
+ branches: [main]
+ schedule:
+ # Weekly so the score reflects security-relevant changes (new
+ # deps, new releases, branch-protection edits) even when there's
+ # no push for a few days. Tuesdays 03:00 UTC keeps it off the
+ # busy weekday-morning window.
+ - cron: "0 3 * * 2"
+ workflow_dispatch:
+
+permissions: read-all
+
+jobs:
+ analysis:
+ name: Scorecard analysis
+ runs-on: ubuntu-latest
+ permissions:
+ # Required for upload-sarif → /security/code-scanning.
+ security-events: write
+ # Required for OIDC publish_results=true → api.scorecard.dev.
+ id-token: write
+ contents: read
+ actions: read
+ steps:
+ - name: Checkout
+ # actions/checkout@v4 = b4ffde65f46336ab88eb53be808477a3936bae11
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+ with:
+ persist-credentials: false
+
+ - name: Run analysis
+ # ossf/scorecard-action@v2.4.3
+ uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ # publish_results=true sends the score to the public registry
+ # so the README badge resolves. It is also a public-good
+ # contribution — anyone evaluating ctm's supply-chain posture
+ # can read the breakdown without re-running the tool.
+ publish_results: true
+
+ - name: Upload artifact
+ # actions/upload-artifact@v7.0.1
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
+
+ - name: Upload to code-scanning
+ # github/codeql-action/upload-sarif@v4.35.2
+ uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225
+ with:
+ sarif_file: results.sarif
diff --git a/README.md b/README.md
index a3cc7b2..166111e 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,30 @@
+
+
+
+
Quickstart ·
Commands ·
From 8e21372358d88a73b277bf4c1a055e89bc8eabf9 Mon Sep 17 00:00:00 2001
From: aksops
Date: Fri, 1 May 2026 10:45:32 +0000
Subject: [PATCH 2/2] ci(scorecard): scope permissions to contents:read at
workflow level
Sonar githubactions:S8234 flagged 'permissions: read-all' as a
vulnerability. Job-level permissions already grant exactly what the
scorecard analyzer needs (security-events: write for SARIF upload,
id-token: write for OIDC publish, contents: read, actions: read);
the top-level grant is only a fallback for any future steps without
their own block, so contents:read is the right minimum.
---
.github/workflows/scorecard.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 28a9efc..c30c3b6 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -27,7 +27,8 @@ on:
- cron: "0 3 * * 2"
workflow_dispatch:
-permissions: read-all
+permissions:
+ contents: read
jobs:
analysis: