From f7d30e78fb86a35b1b560dc7ea53e8c4f481fee2 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Jun 2026 10:47:42 +0000 Subject: [PATCH] =?UTF-8?q?ci(governance):=20harden=20workflows=20?= =?UTF-8?q?=E2=80=94=20timeouts,=20scorecard=20perms,=20secret=20gate,=20c?= =?UTF-8?q?odeql=20actions,=20drop=20privileged=20workflow=5Frun?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clears the pre-existing Hypatia workflow_audit findings (non-blocking, but tidies governance CI): - timeout-minutes on all remaining jobs: release.yml (3), static-analysis-gate.yml (3), rhodibot.yml (1) - instant-sync.yml (HIGH secret_action_without_presence_gate): gate the repository-dispatch step on FARM_DISPATCH_TOKEN presence so it no-ops without the secret - scorecard.yml (HIGH scorecard_wrapper_missing_job_permissions): add job-level permissions to the reusable-wrapper job (security-events/id-token/contents/actions) - codeql.yml (codeql_missing_actions_language): add the `actions` language so workflow files are scanned - rhodibot.yml (CRITICAL): remove the privileged `workflow_run` trigger — it ran with contents/ pull-requests write on Hypatia completion; rhodibot still runs via schedule + workflow_dispatch Verified: all changed workflows parse as YAML; every non-reusable job now has timeout-minutes. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01UCnxjXkN6uDj9YSANuGEgR --- .github/workflows/codeql.yml | 2 ++ .github/workflows/instant-sync.yml | 4 ++++ .github/workflows/release.yml | 3 +++ .github/workflows/rhodibot.yml | 7 ++++--- .github/workflows/scorecard.yml | 5 +++++ .github/workflows/static-analysis-gate.yml | 3 +++ 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 94ba8ff..c433ac9 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -33,6 +33,8 @@ jobs: include: - language: javascript-typescript build-mode: none + - language: actions + build-mode: none steps: - name: Checkout diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index 00531c1..0660bcf 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -16,7 +16,11 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: + - name: Check dispatch token presence + id: gate + run: echo "has_token=${{ secrets.FARM_DISPATCH_TOKEN != '' }}" >> "$GITHUB_OUTPUT" - name: Trigger Propagation + if: steps.gate.outputs.has_token == 'true' uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v3 with: token: ${{ secrets.FARM_DISPATCH_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b80da1c..4c8b9af 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,6 +18,7 @@ jobs: build: name: Build Artifacts runs-on: ubuntu-latest + timeout-minutes: 30 permissions: contents: read steps: @@ -42,6 +43,7 @@ jobs: changelog: name: Generate Changelog runs-on: ubuntu-latest + timeout-minutes: 30 permissions: contents: read outputs: @@ -88,6 +90,7 @@ jobs: name: Create GitHub Release needs: [build, changelog] runs-on: ubuntu-latest + timeout-minutes: 30 permissions: contents: write steps: diff --git a/.github/workflows/rhodibot.yml b/.github/workflows/rhodibot.yml index a82f178..c443eb6 100644 --- a/.github/workflows/rhodibot.yml +++ b/.github/workflows/rhodibot.yml @@ -16,9 +16,9 @@ on: schedule: - cron: '0 6 * * 1' # Every Monday at 06:00 UTC workflow_dispatch: # Manual trigger - workflow_run: - workflows: ["Hypatia Neurosymbolic Analysis"] - types: [completed] + # NOTE: the privileged `workflow_run` trigger (on Hypatia completion) was removed — + # it ran with contents/pull-requests write and was flagged as a critical workflow + # pattern. Rhodibot still runs weekly (schedule) and on demand (workflow_dispatch). permissions: contents: write @@ -27,6 +27,7 @@ permissions: jobs: rhodibot: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 90d6f31..73e4cb6 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -12,5 +12,10 @@ permissions: read-all jobs: analysis: + permissions: + security-events: write + id-token: write + contents: read + actions: read uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@5a93d9d57cc04de4002d6d0ecd336fc7a8698910 secrets: inherit diff --git a/.github/workflows/static-analysis-gate.yml b/.github/workflows/static-analysis-gate.yml index af0a0f3..e4e3cee 100644 --- a/.github/workflows/static-analysis-gate.yml +++ b/.github/workflows/static-analysis-gate.yml @@ -19,6 +19,7 @@ jobs: panic-attack-assail: name: panic-attack assail runs-on: ubuntu-latest + timeout-minutes: 20 steps: - name: Checkout repository @@ -123,6 +124,7 @@ jobs: hypatia-scan: name: Hypatia neurosymbolic scan runs-on: ubuntu-latest + timeout-minutes: 20 steps: - name: Checkout repository @@ -235,6 +237,7 @@ jobs: deposit-findings: name: Deposit findings for gitbot-fleet runs-on: ubuntu-latest + timeout-minutes: 20 needs: [panic-attack-assail, hypatia-scan] if: always()