Skip to content

Commit e973a11

Browse files
bloveclaude
andauthored
ci: supply-chain hardening to raise OSSF Scorecard / HVTrust (#684)
* docs(spec): HVTrust supply-chain hardening design Maps OSSF Scorecard + provenance/signing changes to HVTracker's HVTrust scoring model. Covers Scorecard publishing, hardening files, Renovate with SHA pinning, enforced commit signing, and SLSA release artifacts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(plan): HVTrust supply-chain hardening implementation plan Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(security): add SECURITY.md vulnerability disclosure policy * ci: set least-privilege top-level token permissions on publish workflows * ci: add CodeQL SAST for javascript-typescript and python * ci: add OSSF Scorecard workflow with public results + README badge * ci: add Renovate config with GitHub Action digest pinning * ci: pin all GitHub Actions to commit SHAs * docs(contributing): document required SSH commit signing * ci: generate SLSA provenance for GitHub Release artifacts * ci: enable PyPI build provenance attestations on middleware publish * fix(ci): grant release-provenance build job write perms; pin pypa publish action - build-artifacts needs contents: write for 'gh release upload' - pin pypa/gh-action-pypi-publish to release/v1 SHA (Pinned-Dependencies) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 8c06875 commit e973a11

17 files changed

Lines changed: 1155 additions & 75 deletions

.github/workflows/aimock-drift.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ jobs:
2222
drift:
2323
runs-on: ubuntu-latest
2424
steps:
25-
- uses: actions/checkout@v6.0.2
26-
- uses: actions/setup-node@v6.3.0
25+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
26+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
2727
with:
2828
node-version: 22
2929
cache: npm
@@ -34,7 +34,7 @@ jobs:
3434
run: npx nx run examples-chat-angular:drift --skip-nx-cache
3535
- name: Open issue on drift
3636
if: failure()
37-
uses: actions/github-script@v8
37+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
3838
with:
3939
script: |
4040
const { owner, repo } = context.repo;

.github/workflows/ci.yml

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ jobs:
3333
website_e2e: ${{ steps.scope.outputs.website_e2e }}
3434
posthog: ${{ steps.scope.outputs.posthog }}
3535
steps:
36-
- uses: actions/checkout@v6.0.2
36+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3737
with:
3838
fetch-depth: 0
39-
- uses: actions/setup-node@v6.3.0
39+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
4040
with:
4141
node-version: 22
4242
cache: npm
@@ -85,8 +85,8 @@ jobs:
8585
env:
8686
LIBS: chat,langgraph,ag-ui,render,a2ui,licensing,telemetry
8787
steps:
88-
- uses: actions/checkout@v6.0.2
89-
- uses: actions/setup-node@v6.3.0
88+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
89+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
9090
with:
9191
node-version: 22
9292
cache: npm
@@ -104,10 +104,10 @@ jobs:
104104
permissions:
105105
contents: write
106106
steps:
107-
- uses: actions/checkout@v6.0.2
107+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
108108
with:
109109
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.head_ref || github.sha }}
110-
- uses: actions/setup-node@v6.3.0
110+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
111111
with:
112112
node-version: 22
113113
cache: npm
@@ -137,8 +137,8 @@ jobs:
137137
if: github.event_name == 'push' || needs.ci-scope.outputs.cockpit == 'true'
138138
runs-on: ubuntu-latest
139139
steps:
140-
- uses: actions/checkout@v6.0.2
141-
- uses: actions/setup-node@v6.3.0
140+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
141+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
142142
with:
143143
node-version: 22
144144
cache: npm
@@ -152,10 +152,10 @@ jobs:
152152
if: github.event_name == 'push' || needs.ci-scope.outputs.cockpit_examples == 'true'
153153
runs-on: ubuntu-latest
154154
steps:
155-
- uses: actions/checkout@v6.0.2
155+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
156156
with:
157157
fetch-depth: 0
158-
- uses: actions/setup-node@v6.3.0
158+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
159159
with:
160160
node-version: 22
161161
cache: npm
@@ -183,8 +183,8 @@ jobs:
183183
if: github.event_name == 'push' || needs.ci-scope.outputs.cockpit_smoke == 'true'
184184
runs-on: ubuntu-latest
185185
steps:
186-
- uses: actions/checkout@v6.0.2
187-
- uses: actions/setup-node@v6.3.0
186+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
187+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
188188
with:
189189
node-version: 22
190190
cache: npm
@@ -208,9 +208,9 @@ jobs:
208208
fi
209209
env:
210210
COCKPIT_SECRET_TOKEN: ${{ secrets.COCKPIT_SECRET_TOKEN }}
211-
- uses: actions/checkout@v6.0.2
211+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
212212
if: steps.integration_secret.outputs.enabled == 'true'
213-
- uses: actions/setup-node@v6.3.0
213+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
214214
if: steps.integration_secret.outputs.enabled == 'true'
215215
with:
216216
node-version: 22
@@ -228,8 +228,8 @@ jobs:
228228
if: github.event_name == 'push' || needs.ci-scope.outputs.cockpit_deploy_smoke == 'true'
229229
runs-on: ubuntu-latest
230230
steps:
231-
- uses: actions/checkout@v6.0.2
232-
- uses: actions/setup-node@v6.3.0
231+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
232+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
233233
with:
234234
node-version: 22
235235
cache: npm
@@ -242,18 +242,18 @@ jobs:
242242
if: github.event_name == 'push' || needs.ci-scope.outputs.examples_chat == 'true'
243243
runs-on: ubuntu-latest
244244
steps:
245-
- uses: actions/checkout@v6.0.2
246-
- uses: actions/setup-node@v6.3.0
245+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
246+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
247247
with:
248248
node-version: 22
249249
cache: npm
250250
- name: Install uv
251-
uses: astral-sh/setup-uv@v8.0.0
251+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
252252
with:
253253
python-version: '3.12'
254254
- run: npm ci
255255
- name: Cache examples-chat python venv
256-
uses: actions/cache@v4
256+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
257257
with:
258258
path: examples/chat/python/.venv
259259
key: uv-venv-${{ runner.os }}-py3.12-${{ hashFiles('examples/chat/python/uv.lock') }}
@@ -272,25 +272,25 @@ jobs:
272272
matrix:
273273
shard: [1, 2, 3, 4]
274274
steps:
275-
- uses: actions/checkout@v6.0.2
276-
- uses: actions/setup-node@v6.3.0
275+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
276+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
277277
with:
278278
node-version: 22
279279
cache: npm
280280
- name: Install uv
281-
uses: astral-sh/setup-uv@v8.0.0
281+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
282282
with:
283283
python-version: '3.12'
284284
- run: npm ci
285285
- name: Cache examples-chat python venv
286-
uses: actions/cache@v4
286+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
287287
with:
288288
path: examples/chat/python/.venv
289289
key: uv-venv-${{ runner.os }}-py3.12-${{ hashFiles('examples/chat/python/uv.lock') }}
290290
- working-directory: examples/chat/python
291291
run: uv sync
292292
- name: Cache Playwright browsers
293-
uses: actions/cache@v4
293+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
294294
with:
295295
path: ~/.cache/ms-playwright
296296
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
@@ -300,7 +300,7 @@ jobs:
300300
- run: npx nx e2e examples-chat-angular --skip-nx-cache -- --shard=${{ matrix.shard }}/4
301301
- name: Upload Playwright trace on failure
302302
if: failure()
303-
uses: actions/upload-artifact@v4
303+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
304304
with:
305305
name: examples-chat-e2e-trace-shard-${{ matrix.shard }}
306306
path: |
@@ -332,25 +332,25 @@ jobs:
332332
runs-on: ubuntu-latest
333333
timeout-minutes: 35
334334
steps:
335-
- uses: actions/checkout@v6.0.2
336-
- uses: actions/setup-node@v6.3.0
335+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
336+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
337337
with:
338338
node-version: 22
339339
cache: npm
340340
- name: Install uv
341-
uses: astral-sh/setup-uv@v8.0.0
341+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
342342
with:
343343
python-version: '3.12'
344344
- run: npm ci
345345
- name: Cache examples-ag-ui python venv
346-
uses: actions/cache@v4
346+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
347347
with:
348348
path: examples/ag-ui/python/.venv
349349
key: uv-venv-${{ runner.os }}-py3.12-${{ hashFiles('examples/ag-ui/python/uv.lock') }}
350350
- working-directory: examples/ag-ui/python
351351
run: uv sync
352352
- name: Cache Playwright browsers
353-
uses: actions/cache@v4
353+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
354354
with:
355355
path: ~/.cache/ms-playwright
356356
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
@@ -360,7 +360,7 @@ jobs:
360360
- run: npx nx e2e examples-ag-ui-angular --skip-nx-cache
361361
- name: Upload Playwright trace on failure
362362
if: failure()
363-
uses: actions/upload-artifact@v4
363+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
364364
with:
365365
name: examples-ag-ui-e2e-trace
366366
path: |
@@ -376,10 +376,10 @@ jobs:
376376
outputs:
377377
caps: ${{ steps.matrix.outputs.caps }}
378378
steps:
379-
- uses: actions/checkout@v6.0.2
379+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
380380
with:
381381
fetch-depth: 0
382-
- uses: actions/setup-node@v6.3.0
382+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
383383
with:
384384
node-version: 22
385385
cache: npm
@@ -415,26 +415,26 @@ jobs:
415415
matrix:
416416
cap: ${{ fromJson(needs.cockpit-e2e-dispatcher.outputs.caps) }}
417417
steps:
418-
- uses: actions/checkout@v6.0.2
419-
- uses: actions/setup-node@v6.3.0
418+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
419+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
420420
with:
421421
node-version: 22
422422
cache: npm
423423
- name: Install uv
424-
uses: astral-sh/setup-uv@v8.0.0
424+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
425425
with:
426426
python-version: '3.12'
427427
- run: npm ci
428428
- name: Cache cap python venv
429-
uses: actions/cache@v4
429+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
430430
with:
431431
path: ${{ matrix.cap.python }}/.venv
432432
key: uv-venv-${{ runner.os }}-py3.12-${{ matrix.cap.python }}-${{ hashFiles(format('{0}/uv.lock', matrix.cap.python)) }}
433433
- name: uv sync per-cap python
434434
working-directory: ${{ matrix.cap.python }}
435435
run: uv sync
436436
- name: Cache Playwright browsers
437-
uses: actions/cache@v4
437+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
438438
with:
439439
path: ~/.cache/ms-playwright
440440
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
@@ -445,7 +445,7 @@ jobs:
445445
run: npx nx e2e "${{ matrix.cap.angular }}" --skip-nx-cache
446446
- name: Upload Playwright trace on failure
447447
if: failure()
448-
uses: actions/upload-artifact@v4
448+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
449449
with:
450450
name: cockpit-e2e-trace-${{ matrix.cap.angular }}
451451
path: |
@@ -472,14 +472,14 @@ jobs:
472472
if: github.event_name == 'push' || needs.ci-scope.outputs.website_e2e == 'true'
473473
runs-on: ubuntu-latest
474474
steps:
475-
- uses: actions/checkout@v6.0.2
476-
- uses: actions/setup-node@v6.3.0
475+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
476+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
477477
with:
478478
node-version: 22
479479
cache: npm
480480
- run: npm ci
481481
- name: Cache Playwright browsers
482-
uses: actions/cache@v4
482+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
483483
with:
484484
path: ~/.cache/ms-playwright
485485
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
@@ -608,7 +608,7 @@ jobs:
608608
# Only deploy on pushes to main, not on pull requests
609609
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
610610
steps:
611-
- uses: actions/checkout@v6.0.2
611+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
612612
with:
613613
fetch-depth: 0
614614
- name: Detect deploy-relevant changes
@@ -658,7 +658,7 @@ jobs:
658658
examples_changed=true
659659
fi
660660
echo "changed=$examples_changed" >> "$GITHUB_OUTPUT"
661-
- uses: actions/setup-node@v6.3.0
661+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
662662
if: steps.deploy_preflight.outputs.relevant == 'true' || steps.examples_changed.outputs.changed == 'true'
663663
with:
664664
node-version: 22
@@ -711,7 +711,7 @@ jobs:
711711
echo "cockpit=$cockpit_changed" >> "$GITHUB_OUTPUT"
712712
- name: Cache Playwright browsers
713713
if: steps.affected.outputs.website == 'true'
714-
uses: actions/cache@v4
714+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
715715
with:
716716
path: ~/.cache/ms-playwright
717717
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
@@ -792,8 +792,8 @@ jobs:
792792
echo "::error::examples/chat — e2e finished with ${{ needs.examples-chat-e2e.result }}; refusing to deploy the canonical demo."
793793
exit 1
794794
fi
795-
- uses: actions/checkout@v6.0.2
796-
- uses: actions/setup-node@v6.3.0
795+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
796+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
797797
with:
798798
node-version: 22
799799
cache: npm
@@ -858,7 +858,7 @@ jobs:
858858
runs-on: ubuntu-latest
859859
if: ${{ always() && !cancelled() && github.ref == 'refs/heads/main' && github.event_name == 'push' }}
860860
steps:
861-
- uses: actions/checkout@v6.0.2
861+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
862862
with:
863863
fetch-depth: 0
864864
- name: Require ag-ui demo prerequisite jobs
@@ -887,14 +887,14 @@ jobs:
887887
if [ "$ag_ui_changed" != "true" ]; then
888888
echo "::notice::No ag-ui demo files changed; skipping ag-ui demo deploy."
889889
fi
890-
- uses: actions/setup-node@v6.3.0
890+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
891891
if: steps.ag_ui_changed.outputs.changed == 'true'
892892
with:
893893
node-version: 22
894894
cache: npm
895895
- name: Install uv
896896
if: steps.ag_ui_changed.outputs.changed == 'true'
897-
uses: astral-sh/setup-uv@v8.0.0
897+
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
898898
with:
899899
python-version: '3.12'
900900
- if: steps.ag_ui_changed.outputs.changed == 'true'
@@ -932,8 +932,8 @@ jobs:
932932
runs-on: ubuntu-latest
933933
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
934934
steps:
935-
- uses: actions/checkout@v6.0.2
936-
- uses: actions/setup-node@v6.3.0
935+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
936+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
937937
with:
938938
node-version: 22
939939
cache: npm
@@ -943,7 +943,7 @@ jobs:
943943
env:
944944
LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }}
945945
- name: Cache Playwright browsers
946-
uses: actions/cache@v4
946+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
947947
with:
948948
path: ~/.cache/ms-playwright
949949
key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
@@ -964,7 +964,7 @@ jobs:
964964
if: github.event_name == 'push' || needs.ci-scope.outputs.posthog == 'true'
965965
runs-on: ubuntu-latest
966966
steps:
967-
- uses: actions/checkout@v4
967+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
968968
with:
969969
fetch-depth: 0
970970
- name: Detect PostHog-relevant changes
@@ -990,7 +990,7 @@ jobs:
990990
if [ "$posthog_relevant" != "true" ]; then
991991
echo "::notice::No PostHog tooling files changed — skipping dependency setup and drift check."
992992
fi
993-
- uses: actions/setup-node@v4
993+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
994994
if: steps.posthog_preflight.outputs.relevant == 'true'
995995
with:
996996
node-version: '20'

0 commit comments

Comments
 (0)