From e0605c49ae0a4a96b2fa90568cf0381d1f1f5cae Mon Sep 17 00:00:00 2001 From: Christopher Sellers <1@christophersellers.com> Date: Fri, 23 Oct 2026 08:23:00 -0700 Subject: [PATCH 1/3] ci: list 9 missing workflows in inventory; stop action-pin matching 'statuses:' permissions --- .github/workflows/copy-lint.yml | 4 ++-- scripts/ci/check_supply_chain.py | 2 +- scripts/workflow_inventory.txt | 9 +++++++++ tests/scripts/test_check_supply_chain.py | 11 +++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/.github/workflows/copy-lint.yml b/.github/workflows/copy-lint.yml index 80fb0db51..606033b89 100644 --- a/.github/workflows/copy-lint.yml +++ b/.github/workflows/copy-lint.yml @@ -20,8 +20,8 @@ jobs: report: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6 + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6 with: node-version: '20' - run: node --test scripts/copy-lint/check-copy.test.mjs diff --git a/scripts/ci/check_supply_chain.py b/scripts/ci/check_supply_chain.py index 9902f8204..9e0e1b779 100644 --- a/scripts/ci/check_supply_chain.py +++ b/scripts/ci/check_supply_chain.py @@ -35,7 +35,7 @@ from pathlib import Path SHA40 = re.compile(r"^[0-9a-f]{40}$") -USES_RE = re.compile(r"[\"']?uses[\"']?:\s*[\"']?([A-Za-z0-9_.\-/]+)(?:@([^\"'#\s]+))?[\"']?") +USES_RE = re.compile(r"(? None: assert mod.check_action_pin(path, "ok.yml") == [] +def test_action_pin_ignores_status_permissions_but_checks_uses(repo: Path) -> None: + path = _write( + repo, + ".github/workflows/statuses.yml", + "permissions:\n statuses: write\n statuses: read\nsteps:\n - uses: actions/checkout@v4\n - {uses: actions/setup-node@v4}\n", + ) + violations = mod.check_action_pin(path, "statuses.yml") + assert [v.line for v in violations] == [5, 6] + assert [v.rule for v in violations] == ["action-pin", "action-pin"] + + def test_action_pin_rejects_tag_ref(repo: Path) -> None: path = _write(repo, ".github/workflows/bad.yml", "steps:\n - uses: actions/checkout@v4\n") violations = mod.check_action_pin(path, "bad.yml") From 30cc4833737e1fde4e29ae78441d02e849b379ac Mon Sep 17 00:00:00 2001 From: Christopher Sellers <1@christophersellers.com> Date: Fri, 23 Oct 2026 14:37:35 -0700 Subject: [PATCH 2/3] ci: clear detect-secrets false positive in vercel-preview-guard --- .github/workflows/vercel-preview-guard.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/vercel-preview-guard.yml b/.github/workflows/vercel-preview-guard.yml index fcb62cbcd..85d46ad9d 100644 --- a/.github/workflows/vercel-preview-guard.yml +++ b/.github/workflows/vercel-preview-guard.yml @@ -107,22 +107,22 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 env: PREVIEW_URL: ${{ needs.preview.outputs.preview_url }} - BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }} + BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }} # pragma: allowlist secret with: github-token: ${{ github.token }} script: | const marker = ''; - const secret = process.env.BYPASS_SECRET; - if (secret) core.setSecret(secret); // Emits ::add-mask:: before using it. + const bypassValue = process.env.BYPASS_SECRET; + if (bypassValue) core.setSecret(bypassValue); // Emits ::add-mask:: before using it. const preview = process.env.PREVIEW_URL; if (!preview) throw new Error('The preview job did not return an access URL'); const url = new URL(preview); - if (secret) { - url.searchParams.set('x-vercel-protection-bypass', secret); + if (bypassValue) { + url.searchParams.set('x-vercel-protection-bypass', bypassValue); url.searchParams.set('x-vercel-set-bypass-cookie', 'true'); } const body = `${marker}\nVercel preview: ${url.toString()}` + - (secret ? '' : '\n\nThe bypass secret is not configured.'); + (bypassValue ? '' : '\n\nThe bypass secret is not configured.'); const { owner, repo } = context.repo; const issue_number = context.issue.number; const comments = await github.paginate(github.rest.issues.listComments, { From 182a4e45487817e120abb82a8606d95d64cc94d9 Mon Sep 17 00:00:00 2001 From: Christopher Sellers <1@christophersellers.com> Date: Fri, 23 Oct 2026 14:51:04 -0700 Subject: [PATCH 3/3] ci: refresh .secrets.baseline line numbers (detect-secrets 1.5.0, no new findings) --- .secrets.baseline | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index dc26a198f..20d3aa5c8 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -141,35 +141,35 @@ "filename": ".github/workflows/backend-ci.yml", "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", "is_verified": false, - "line_number": 136 + "line_number": 132 }, { "type": "Basic Auth Credentials", "filename": ".github/workflows/backend-ci.yml", "hashed_secret": "afc848c316af1a89d49826c5ae9d00ed769415f3", "is_verified": false, - "line_number": 219 + "line_number": 215 }, { "type": "Secret Keyword", "filename": ".github/workflows/backend-ci.yml", "hashed_secret": "b71d494da8d930401ba9b32b7cef87295f3eb6d3", "is_verified": false, - "line_number": 223 + "line_number": 219 }, { "type": "Secret Keyword", "filename": ".github/workflows/backend-ci.yml", "hashed_secret": "d86daa0361b89a2c9f4b95648b9ad17edf6f92ae", "is_verified": false, - "line_number": 229 + "line_number": 225 }, { "type": "Secret Keyword", "filename": ".github/workflows/backend-ci.yml", "hashed_secret": "eec69da96b4b2984741269925f0a8e46a1e03468", "is_verified": false, - "line_number": 231 + "line_number": 227 } ], ".github/workflows/frontend-ci.yml": [ @@ -3203,22 +3203,13 @@ "line_number": 142 } ], - "services/ingestion/tests/test_epcis_gln_check_digit.py": [ - { - "type": "Hex High Entropy String", - "filename": "services/ingestion/tests/test_epcis_gln_check_digit.py", - "hashed_secret": "8e4456ef140191dfda4a6d287b36e5451d1d7d79", - "is_verified": false, - "line_number": 64 - } - ], "services/ingestion/tests/test_epcis_tenant_isolation.py": [ { "type": "Secret Keyword", "filename": "services/ingestion/tests/test_epcis_tenant_isolation.py", "hashed_secret": "9762e53f3b6420f10041406e88c337725670824b", "is_verified": false, - "line_number": 135 + "line_number": 124 } ], "services/ingestion/tests/test_fsma_plugin_catalog.py": [ @@ -3275,15 +3266,6 @@ "line_number": 276 } ], - "services/ingestion/tests/test_qa4_webhook_inbound.py": [ - { - "type": "Secret Keyword", - "filename": "services/ingestion/tests/test_qa4_webhook_inbound.py", - "hashed_secret": "a62f2225bf70bfaccbc7f1ef2a397836717377de", - "is_verified": false, - "line_number": 121 - } - ], "services/ingestion/tests/test_regengine_sources_rest_qa.py": [ { "type": "Hex High Entropy String", @@ -4176,5 +4158,5 @@ } ] }, - "generated_at": "2026-10-23T09:48:32Z" + "generated_at": "2026-10-23T21:50:55Z" }