|
| 1 | +# OpenSSF Scorecard Setup #443 Implementation Plan |
| 2 | + |
| 3 | +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. |
| 4 | +
|
| 5 | +**Goal:** Add OpenSSF Scorecard GitHub Action workflow, display the scorecard badge in README, and achieve an initial score ≥ 6/10 to establish security credibility for enterprise evaluators. |
| 6 | + |
| 7 | +**Architecture:** Single new GitHub Actions workflow file triggers on push to main, weekly schedule, and PRs. Results are published to GitHub's security dashboard as SARIF. Badge in README links to the public scorecard entry. No code changes — configuration only. |
| 8 | + |
| 9 | +**Tech Stack:** GitHub Actions, ossf/scorecard-action v2, github/codeql-action v3, SARIF |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +## File Map |
| 14 | + |
| 15 | +- Create: `.github/workflows/scorecard.yml` — OpenSSF Scorecard CI workflow |
| 16 | +- Modify: `README.md` — add scorecard badge below existing badges |
| 17 | +- Verify: `.github/dependabot.yml` — already configured (no changes needed) |
| 18 | +- Verify: `SECURITY.md` — already exists (no changes needed) |
| 19 | + |
| 20 | +--- |
| 21 | + |
| 22 | +### Task 1: Audit prerequisites |
| 23 | + |
| 24 | +**Files:** |
| 25 | +- Read: `.github/workflows/` directory |
| 26 | +- Read: `README.md` badge section |
| 27 | +- Read: `SECURITY.md` |
| 28 | + |
| 29 | +- [ ] **Step 1: List existing workflows** |
| 30 | + |
| 31 | +```bash |
| 32 | +ls .github/workflows/ |
| 33 | +``` |
| 34 | + |
| 35 | +Expected: existing workflows like `ci.yml`, `security.yml`, `release.yml`, etc. |
| 36 | +Confirm: no `scorecard.yml` yet. |
| 37 | + |
| 38 | +- [ ] **Step 2: Check README badge section** |
| 39 | + |
| 40 | +```bash |
| 41 | +head -20 README.md |
| 42 | +``` |
| 43 | + |
| 44 | +Expected: existing badges like Go version, license, test status. Note the badge format used. |
| 45 | + |
| 46 | +- [ ] **Step 3: Verify SECURITY.md exists** |
| 47 | + |
| 48 | +```bash |
| 49 | +ls SECURITY.md |
| 50 | +``` |
| 51 | + |
| 52 | +Expected: file exists. The OpenSSF Scorecard checks for SECURITY.md — it already passes. |
| 53 | + |
| 54 | +- [ ] **Step 4: Verify dependabot.yml exists** |
| 55 | + |
| 56 | +```bash |
| 57 | +cat .github/dependabot.yml |
| 58 | +``` |
| 59 | + |
| 60 | +Expected: file exists with `package-ecosystem: gomod` and `package-ecosystem: github-actions`. Both are required for Scorecard's "Dependency-Update-Tool" check. |
| 61 | + |
| 62 | +--- |
| 63 | + |
| 64 | +### Task 2: Create the OpenSSF Scorecard workflow |
| 65 | + |
| 66 | +**Files:** |
| 67 | +- Create: `.github/workflows/scorecard.yml` |
| 68 | + |
| 69 | +- [ ] **Step 1: Create the workflow file** |
| 70 | + |
| 71 | +```yaml |
| 72 | +# .github/workflows/scorecard.yml |
| 73 | +name: OpenSSF Scorecard |
| 74 | + |
| 75 | +on: |
| 76 | + # Run on every push to the default branch |
| 77 | + push: |
| 78 | + branches: [main] |
| 79 | + # Run weekly on Saturday at 01:30 UTC to keep results fresh |
| 80 | + schedule: |
| 81 | + - cron: '30 1 * * 6' |
| 82 | + # Allow manual trigger |
| 83 | + workflow_dispatch: |
| 84 | + |
| 85 | +# Restrict permissions to least-privilege |
| 86 | +permissions: read-all |
| 87 | + |
| 88 | +jobs: |
| 89 | + analysis: |
| 90 | + name: Scorecard analysis |
| 91 | + runs-on: ubuntu-latest |
| 92 | + permissions: |
| 93 | + # Needed for OIDC token for publishing results |
| 94 | + id-token: write |
| 95 | + # Needed to upload SARIF results to GitHub Code Scanning |
| 96 | + security-events: write |
| 97 | + # Needed to read actions configuration |
| 98 | + actions: read |
| 99 | + # Needed to check out code |
| 100 | + contents: read |
| 101 | + |
| 102 | + steps: |
| 103 | + - name: Checkout code |
| 104 | + uses: actions/checkout@v4 |
| 105 | + with: |
| 106 | + persist-credentials: false |
| 107 | + |
| 108 | + - name: Run OpenSSF Scorecard analysis |
| 109 | + uses: ossf/scorecard-action@v2.4.0 |
| 110 | + with: |
| 111 | + results_file: results.sarif |
| 112 | + results_format: sarif |
| 113 | + # Publish results to the OpenSSF public dashboard |
| 114 | + publish_results: true |
| 115 | + |
| 116 | + - name: Upload SARIF artifact for debugging |
| 117 | + uses: actions/upload-artifact@v4 |
| 118 | + with: |
| 119 | + name: SARIF file |
| 120 | + path: results.sarif |
| 121 | + retention-days: 5 |
| 122 | + |
| 123 | + - name: Upload results to GitHub Code Scanning |
| 124 | + uses: github/codeql-action/upload-sarif@v3 |
| 125 | + with: |
| 126 | + sarif_file: results.sarif |
| 127 | +``` |
| 128 | +
|
| 129 | +- [ ] **Step 2: Verify YAML syntax** |
| 130 | +
|
| 131 | +```bash |
| 132 | +python3 -c "import yaml; yaml.safe_load(open('.github/workflows/scorecard.yml'))" && echo "YAML valid" |
| 133 | +``` |
| 134 | + |
| 135 | +Expected: `YAML valid` |
| 136 | + |
| 137 | +- [ ] **Step 3: Commit the workflow** |
| 138 | + |
| 139 | +```bash |
| 140 | +git add .github/workflows/scorecard.yml |
| 141 | +git commit -m "ci: add OpenSSF Scorecard GitHub Actions workflow (#443)" |
| 142 | +``` |
| 143 | + |
| 144 | +--- |
| 145 | + |
| 146 | +### Task 3: Add scorecard badge to README |
| 147 | + |
| 148 | +**Files:** |
| 149 | +- Modify: `README.md` |
| 150 | + |
| 151 | +- [ ] **Step 1: Identify badge placement** |
| 152 | + |
| 153 | +```bash |
| 154 | +grep -n "!\[" README.md | head -10 |
| 155 | +``` |
| 156 | + |
| 157 | +Expected: existing badges on lines 1-5. Note the line number of the last existing badge. |
| 158 | + |
| 159 | +- [ ] **Step 2: Add the OpenSSF Scorecard badge** |
| 160 | + |
| 161 | +The badge URL format for OpenSSF Scorecard is: |
| 162 | +`https://api.securityscorecards.dev/projects/github.com/ajitpratap0/GoSQLX/badge` |
| 163 | + |
| 164 | +The link URL is: |
| 165 | +`https://securityscorecards.dev/viewer/?uri=github.com/ajitpratap0/GoSQLX` |
| 166 | + |
| 167 | +Find the badge block in README.md and add after the existing badges: |
| 168 | + |
| 169 | +```markdown |
| 170 | +[](https://securityscorecards.dev/viewer/?uri=github.com/ajitpratap0/GoSQLX) |
| 171 | +``` |
| 172 | + |
| 173 | +Add it adjacent to existing security/quality badges. Use the Edit tool to insert it in the right position. |
| 174 | + |
| 175 | +- [ ] **Step 3: Verify README renders correctly** |
| 176 | + |
| 177 | +```bash |
| 178 | +grep -n "OpenSSF" README.md |
| 179 | +``` |
| 180 | + |
| 181 | +Expected: one line with the badge markdown. |
| 182 | + |
| 183 | +- [ ] **Step 4: Commit the badge** |
| 184 | + |
| 185 | +```bash |
| 186 | +git add README.md |
| 187 | +git commit -m "docs: add OpenSSF Scorecard badge to README (#443)" |
| 188 | +``` |
| 189 | + |
| 190 | +--- |
| 191 | + |
| 192 | +### Task 4: Push and verify the workflow runs |
| 193 | + |
| 194 | +- [ ] **Step 1: Push the branch** |
| 195 | + |
| 196 | +```bash |
| 197 | +git push origin HEAD |
| 198 | +``` |
| 199 | + |
| 200 | +- [ ] **Step 2: Check workflow triggered** |
| 201 | + |
| 202 | +```bash |
| 203 | +gh run list --workflow=scorecard.yml --limit=3 |
| 204 | +``` |
| 205 | + |
| 206 | +Expected: one run in `queued` or `in_progress` state. |
| 207 | + |
| 208 | +- [ ] **Step 3: Watch the run complete** |
| 209 | + |
| 210 | +```bash |
| 211 | +gh run watch |
| 212 | +``` |
| 213 | + |
| 214 | +Expected: run completes in ~2 minutes. Exit code 0. |
| 215 | + |
| 216 | +- [ ] **Step 4: Check SARIF uploaded to Code Scanning** |
| 217 | + |
| 218 | +```bash |
| 219 | +gh api repos/ajitpratap0/GoSQLX/code-scanning/sarifs --jq '.[0].state' |
| 220 | +``` |
| 221 | + |
| 222 | +Expected: `"uploaded"` or `"complete"` |
| 223 | + |
| 224 | +- [ ] **Step 5: View initial score** |
| 225 | + |
| 226 | +After the run completes, the results appear at: |
| 227 | +`https://securityscorecards.dev/viewer/?uri=github.com/ajitpratap0/GoSQLX` |
| 228 | + |
| 229 | +The initial score should be ≥ 6/10 because: |
| 230 | +- SECURITY.md exists ✅ |
| 231 | +- dependabot.yml exists (gomod + github-actions) ✅ |
| 232 | +- GitHub Actions workflows exist ✅ |
| 233 | +- Branch protection on main ✅ |
| 234 | +- License file exists ✅ |
| 235 | +- No critical CVEs (govulncheck in CI) ✅ |
| 236 | + |
| 237 | +Expected failing checks initially: |
| 238 | +- `Signed-Releases` (not signing releases yet — address separately) |
| 239 | +- `Binary-Artifacts` (if any pre-built binaries committed) |
| 240 | + |
| 241 | +--- |
| 242 | + |
| 243 | +### Task 5: Create PR and close issue |
| 244 | + |
| 245 | +- [ ] **Step 1: Create PR** |
| 246 | + |
| 247 | +```bash |
| 248 | +gh pr create \ |
| 249 | + --title "ci: add OpenSSF Scorecard workflow and README badge (#443)" \ |
| 250 | + --body "Closes #443. |
| 251 | +
|
| 252 | +## Changes |
| 253 | +- Adds \`.github/workflows/scorecard.yml\` (ossf/scorecard-action@v2.4.0) |
| 254 | +- Publishes SARIF results to GitHub Code Scanning dashboard |
| 255 | +- Adds OpenSSF Scorecard badge to README |
| 256 | +
|
| 257 | +## Initial Score |
| 258 | +Expected ≥ 6/10. SECURITY.md, dependabot, branch protection, license, govulncheck all passing. |
| 259 | +
|
| 260 | +## Remaining Items |
| 261 | +- Signed releases (Scorecard: Signed-Releases) — future work |
| 262 | +" |
| 263 | +``` |
| 264 | + |
| 265 | +--- |
| 266 | + |
| 267 | +## Self-Review Checklist |
| 268 | + |
| 269 | +- [x] Workflow uses `persist-credentials: false` (Scorecard requirement) |
| 270 | +- [x] Workflow uses `permissions: read-all` at top level + per-job overrides (least privilege) |
| 271 | +- [x] `publish_results: true` enables the public badge |
| 272 | +- [x] SARIF uploaded to GitHub Code Scanning for dashboard visibility |
| 273 | +- [x] Badge URL uses official `api.securityscorecards.dev` endpoint |
| 274 | +- [x] No code changes — config + docs only |
| 275 | +- [x] SECURITY.md existence verified (already satisfies that check) |
| 276 | +- [x] dependabot.yml existence verified (already satisfies Dependency-Update-Tool) |
0 commit comments