{"id":26633510,"url":"https://github.com/chains-project/ghasum","last_synced_at":"2026-01-04T17:14:46.642Z","repository":{"id":222994727,"uuid":"758931760","full_name":"chains-project/ghasum","owner":"chains-project","description":"Checksums for GitHub Actions.","archived":false,"fork":false,"pushed_at":"2025-11-18T03:11:40.000Z","size":422,"stargazers_count":16,"open_issues_count":15,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-18T05:24:33.810Z","etag":null,"topics":["checksums","gha","lockfile"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chains-project.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-02-17T13:57:27.000Z","updated_at":"2025-11-12T07:16:20.000Z","dependencies_parsed_at":"2025-05-24T20:21:43.158Z","dependency_job_id":"646df18b-5802-4f29-81ed-07b20198d9c1","html_url":"https://github.com/chains-project/ghasum","commit_stats":null,"previous_names":["ericcornelissen/ghasum","chains-project/ghasum"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/chains-project/ghasum","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chains-project%2Fghasum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chains-project%2Fghasum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chains-project%2Fghasum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chains-project%2Fghasum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chains-project","download_url":"https://codeload.github.com/chains-project/ghasum/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chains-project%2Fghasum/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27738655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-14T02:00:11.348Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["checksums","gha","lockfile"],"created_at":"2025-03-24T15:15:11.888Z","updated_at":"2026-01-04T17:14:46.634Z","avatar_url":"https://github.com/chains-project.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- SPDX-License-Identifier: CC-BY-4.0 --\u003e\n\n# `ghasum`\n\nChecksums for GitHub Actions.\n\nCompute and verify checksums for all GitHub Actions in a project to guarantee\nthat the Actions you choose to include haven't changed since. `ghasum` gives\nbetter integrity guarantees than pinning Actions by commit hash and is also more\nuser friendly as well.\n\n## Usage\n\nTo start using `ghasum` navigate to a project that use GitHub Actions and run:\n\n```shell\nghasum init\n```\n\nCommit the `gha.sum` file that is created so that the checksums can be verified\nin the future. To verify run:\n\n```shell\nghasum verify\n```\n\nFor further help with using `ghasum` run:\n\n```shell\nghasum help\n```\n\n## Integration\n\nTo use `ghasum` in your GitHub Actions workflows there are two options. One is\nto create and use a local action that runs `ghasum` (recommended) and the other\nis to run `ghasum` inline in every job.\n\n### Local Action (Recommended)\n\nTo integrate `ghasum` as a local action into your GitHub Actions workflows you\nhave to create the local action and then use it in every job in every workflow.\n\n1. \u003cdetails\u003e\n\n   \u003csummary\u003eCreate a local action to run \u003ccode\u003eghasum\u003c/code\u003e:\u003c/summary\u003e\n\n   Create the file `.github/actions/ghasum/action.yml` and copy the following\n   content into the file. Then fill in the `ghasum` version and checksums.\n\n   ```yaml\n   name: ghasum\n   description: Verify checksums of actions\n\n   inputs:\n     checksum:\n       description: The checksum of the ghasum checksums file\n       required: false\n       # TODO: Set the 'checksums-sha512.txt' file's checksum on the next line.\n       default: sha256:4e70619...\n     mode:\n       description: Whether to 'verify' checksums or just 'install' ghasum\n       required: false\n       default: verify\n     version:\n       description: The version of ghasum to use\n       required: false\n       # TODO: Set the ghasum version on the next line.\n       default: vX.Y.Z\n\n   runs:\n     using: composite\n     steps:\n       - name: Validate input 'mode'\n         if: inputs.mode != 'verify' \u0026\u0026 inputs.mode != 'install'\n         shell: bash\n         env:\n           MODE: ${{ inputs.mode }}\n         run: |\n           echo \"mode must be 'verify' or 'install', got: $MODE\"\n           exit 1\n\n       # Unix\n       - name: Initialize ghasum directory\n         if: runner.os == 'macOS' || runner.os == 'Linux'\n         shell: bash\n         run: mkdir -p /tmp/ghasum\n       - name: Download ghasum checksums\n         if: runner.os == 'macOS' || runner.os == 'Linux'\n         shell: bash\n         working-directory: /tmp/ghasum\n         env:\n           CHECKSUM: ${{ inputs.checksum }}\n           GH_TOKEN: ${{ github.token }}\n           VERSION: ${{ inputs.version }}\n         run: |\n           ARTIFACT='checksums-sha512.txt'\n           gh release download \"$VERSION\" --repo chains-project/ghasum --pattern \"$ARTIFACT\"\n           echo \"${CHECKSUM#sha256:}  $ARTIFACT\" | shasum -a 256 -c -\n\n       # Windows\n       - name: Initialize ghasum directory\n         if: runner.os == 'Windows'\n         shell: pwsh\n         run: mkdir C:\\ghasum\n       - name: Download ghasum checksums\n         if: runner.os == 'Windows'\n         shell: pwsh\n         working-directory: C:\\ghasum\n         env:\n           CHECKSUM: ${{ inputs.checksum }}\n           GH_TOKEN: ${{ github.token }}\n           VERSION: ${{ inputs.version }}\n         run: |\n           $ARTIFACT = \"checksums-sha512.txt\"\n           gh release download \"$env:VERSION\" --repo chains-project/ghasum --pattern \"$ARTIFACT\"\n           if ((Get-FileHash -Algorithm SHA256 \"$ARTIFACT\").Hash -ne ($env:CHECKSUM -replace '^sha256:', '')) {\n             Write-Error 'Checksum mismatch!'\n             exit 1\n           } else {\n             Write-Host 'Checksum match'\n           }\n\n       # macOS\n       - name: Pick the ghasum CLI (amd64)\n         if: runner.os == 'macOS' \u0026\u0026 runner.arch == 'X64'\n         id: pick-macos-amd64\n         shell: bash\n         run: echo 'artifact=ghasum_darwin_amd64.tar.gz' \u003e\u003e\"$GITHUB_OUTPUT\"\n       - name: Pick the ghasum CLI (arm64)\n         if: runner.os == 'macOS' \u0026\u0026 runner.arch == 'ARM64'\n         id: pick-macos-arm64\n         shell: bash\n         run: echo 'artifact=ghasum_darwin_arm64.tar.gz' \u003e\u003e\"$GITHUB_OUTPUT\"\n       - name: Download the ghasum CLI\n         if: runner.os == 'macOS'\n         shell: bash\n         working-directory: /tmp/ghasum\n         env:\n           ARTIFACT: ${{ steps.pick-macos-amd64.outputs.artifact || steps.pick-macos-arm64.outputs.artifact }}\n           GH_TOKEN: ${{ github.token }}\n           VERSION: ${{ inputs.version }}\n         run: |\n           gh release download \"$VERSION\" --repo chains-project/ghasum --pattern \"$ARTIFACT\"\n           shasum --check --ignore-missing checksums-sha512.txt\n           tar -xf \"$ARTIFACT\"\n       - name: Verify the action checksums\n         if: runner.os == 'macOS' \u0026\u0026 inputs.mode == 'verify'\n         shell: bash\n         env:\n           JOB: ${{ github.job }}\n           WORKFLOW: ${{ github.workflow_ref }}\n         run: |\n           WORKFLOW=$(echo \"$WORKFLOW\" | cut -d '@' -f 1 | cut -d '/' -f 3-5)\n           /tmp/ghasum/ghasum verify -cache /Users/runner/work/_actions -no-evict -offline \"$WORKFLOW:$JOB\"\n\n       # Linux\n       - name: Pick the ghasum CLI (amd64)\n         if: runner.os == 'Linux' \u0026\u0026 runner.arch == 'X64'\n         id: pick-linux-amd64\n         shell: bash\n         run: echo 'artifact=ghasum_linux_amd64.tar.gz' \u003e\u003e\"$GITHUB_OUTPUT\"\n       - name: Pick the ghasum CLI (arm64)\n         if: runner.os == 'Linux' \u0026\u0026 runner.arch == 'ARM64'\n         id: pick-linux-arm64\n         shell: bash\n         run: echo 'artifact=ghasum_linux_arm64.tar.gz' \u003e\u003e\"$GITHUB_OUTPUT\"\n       - name: Download the ghasum CLI\n         if: runner.os == 'Linux'\n         shell: bash\n         working-directory: /tmp/ghasum\n         env:\n           ARTIFACT: ${{ steps.pick-linux-amd64.outputs.artifact || steps.pick-linux-arm64.outputs.artifact }}\n           GH_TOKEN: ${{ github.token }}\n           VERSION: ${{ inputs.version }}\n         run: |\n           gh release download \"$VERSION\" --repo chains-project/ghasum --pattern \"$ARTIFACT\"\n           shasum --check --ignore-missing checksums-sha512.txt\n           tar -xf \"$ARTIFACT\"\n       - name: Verify the action checksums\n         if: runner.os == 'Linux' \u0026\u0026 inputs.mode == 'verify'\n         shell: bash\n         env:\n           JOB: ${{ github.job }}\n           WORKFLOW: ${{ github.workflow_ref }}\n         run: |\n           WORKFLOW=$(echo \"$WORKFLOW\" | cut -d '@' -f 1 | cut -d '/' -f 3-5)\n           /tmp/ghasum/ghasum verify -cache /home/runner/work/_actions -no-evict -offline \"$WORKFLOW:$JOB\"\n\n       # Windows\n       - name: Pick the ghasum CLI (amd64)\n         if: runner.os == 'Windows' \u0026\u0026 runner.arch == 'X64'\n         id: pick-windows-amd64\n         shell: pwsh\n         run: |\n           'artifact=ghasum_windows_amd64.zip' \u003e\u003e\"$env:GITHUB_OUTPUT\"\n       - name: Pick the ghasum CLI (arm64)\n         if: runner.os == 'Windows' \u0026\u0026 runner.arch == 'ARM64'\n         id: pick-windows-arm64\n         shell: pwsh\n         run: |\n           'artifact=ghasum_windows_arm64.zip' \u003e\u003e\"$env:GITHUB_OUTPUT\"\n       - name: Download the ghasum CLI\n         if: runner.os == 'Windows'\n         shell: pwsh\n         working-directory: C:\\ghasum\n         env:\n           ARTIFACT: ${{ steps.pick-windows-amd64.outputs.artifact || steps.pick-windows-arm64.outputs.artifact }}\n           GH_TOKEN: ${{ github.token }}\n           VERSION: ${{ inputs.version }}\n         run: |\n           gh release download \"$env:VERSION\" --repo chains-project/ghasum --pattern \"$env:ARTIFACT\"\n           $line = Get-Content checksums-sha512.txt | Where-Object { $_ -match \"\\b$env:ARTIFACT$\" }\n           if (-not $line) {\n             Write-Error 'Checksum missing'\n             exit 2\n           } else {\n             if ($line -match \"^([a-fA-F0-9]+)  $env:ARTIFACT$\") {\n               $want = $matches[1]\n               $got = (Get-FileHash -Path $env:ARTIFACT -Algorithm SHA512).Hash\n               if ($got.ToLower() -ne $want.ToLower()) {\n                 Write-Error 'Checksum mismatch'\n                 exit 1\n               } else {\n                 Write-Host 'Checksum match'\n                 Expand-Archive -Path \"$env:ARTIFACT\" -DestinationPath .\n               }\n             } else {\n               Write-Error 'Checksums malformed'\n               exit 2\n             }\n           }\n       - name: Verify the action checksums\n         if: runner.os == 'Windows' \u0026\u0026 inputs.mode == 'verify'\n         shell: pwsh\n         env:\n           JOB: ${{ github.job }}\n           WORKFLOW: ${{ github.workflow_ref }}\n         run: |\n           $WorkflowParts = $env:WORKFLOW -split '@'\n           $WorkflowPath = ($WorkflowParts[0] -split '/')[2..4] -join '/'\n           if (Test-Path -Path 'C:\\a\\_actions') {\n             C:\\ghasum\\ghasum.exe verify -cache C:\\a\\_actions -no-evict -offline \"${WorkflowPath}:$env:JOB\"\n           } else {\n             C:\\ghasum\\ghasum.exe verify -cache D:\\a\\_actions -no-evict -offline \"${WorkflowPath}:$env:JOB\"\n           }\n\n       # Invalidate actions\n       - name: Remove actions\n         if: failure() \u0026\u0026 runner.os == 'Linux'\n         shell: bash\n         run: rm -rf /home/runner/work/_actions\n       - name: Remove actions\n         if: failure() \u0026\u0026 runner.os == 'macOS'\n         shell: bash\n         run: rm -rf /Users/runner/work/_actions\n       - name: Remove actions\n         if: failure() \u0026\u0026 runner.os == 'Windows'\n         shell: pwsh\n         run: |\n           if (Test-Path -Path 'C:\\a\\_actions') {\n             Remove-Item -Recurse -Force -Path C:\\a\\_actions\n           } else {\n             Remove-Item -Recurse -Force -Path D:\\a\\_actions\n           }\n\n       # Expose\n       - name: Expose ghasum binary\n         if: runner.os == 'macOS' || runner.os == 'Linux'\n         shell: bash\n         run: echo '/tmp/ghasum' \u003e\u003e\"$GITHUB_PATH\"\n       - name: Expose ghasum.exe binary\n         if: runner.os == 'Windows'\n         shell: pwsh\n         run: echo 'C:\\ghasum' \u003e\u003e\"$GITHUB_PATH\"\n   ```\n\n   \u003c/details\u003e\n\n2. \u003cdetails\u003e\n\n   \u003csummary\u003eUse the local action in your workflows:\u003c/summary\u003e\n\n   ```yaml\n   jobs:\n     example:\n       steps:\n       # The repository has to be checked out before verifying checksums because\n       #  it requires access to the content in .github/workflows. Because this\n       #  action is run before the checksums are verified it should be pinned to\n       #  a commit SHA.\n       - name: Checkout repository\n         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2\n\n       # Verify the checksums with ghasum through the local action.\n       - name: Verify action checksums\n         uses: ./.github/actions/ghasum\n\n       # The rest of your job ...\n   ```\n\n   \u003c/details\u003e\n\n### Inline\n\n\u003cdetails\u003e\n\n\u003csummary\u003eFor Ubuntu runners\u003c/summary\u003e\n\n```yaml\njob:\n  runs-on: ubuntu-24.04 # Also 'ubuntu-latest'\n  steps:\n  # The repository has to be checked out before verifying checksums because it\n  #  requires access to the content in .github/workflows. Because this action is\n  #  run before the checksums are verified it should be pinned to a commit SHA.\n  - name: Checkout repository\n    uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2\n\n  # Verify the action checksums with ghasum.\n  - name: Verify action checksums\n    env:\n      VERSION: vX.Y.Z                # Set the ghasum version.\n      CHECKSUM: f5f2ff0...           # Set the ghasum binary checksum.\n      GH_TOKEN: ${{ github.token }}  # Required for the GitHub CLI (`gh`).\n      JOB: ${{ github.job }}\n      WORKFLOW: ${{ github.workflow_ref }}\n    run: |\n      # Download the ghasum CLI\n      ARTIFACT=\"ghasum_linux_amd64.tar.gz\"\n      gh release download \"${VERSION}\" --repo chains-project/ghasum --pattern \"${ARTIFACT}\"\n      echo \"${CHECKSUM}  ${ARTIFACT}\" | shasum -a 512 -c -\n      tar -xf \"${ARTIFACT}\"\n\n      # Verify the action checksums\n      WORKFLOW=$(echo \"${WORKFLOW}\" | cut -d '@' -f 1 | cut -d '/' -f 3-5)\n      ./ghasum verify -cache /home/runner/work/_actions -no-evict -offline \"${WORKFLOW}:${JOB}\"\n\n  # The rest of your job ...\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eFor macOS runners\u003c/summary\u003e\n\nFor newer ARM-based runners:\n\n```yaml\njob:\n  runs-on: macos-15 # Also 'macos-latest'\n  steps:\n  # The repository has to be checked out before verifying checksums because it\n  #  requires access to the content in .github/workflows. Because this action is\n  #  run before the checksums are verified it should be pinned to a commit SHA.\n  - name: Checkout repository\n    uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2\n\n  # Verify the action checksums with ghasum.\n  - name: Verify action checksums\n    env:\n      VERSION: vX.Y.Z                # Set the ghasum version.\n      CHECKSUM: 94a5919...           # Set the ghasum binary checksum.\n      GH_TOKEN: ${{ github.token }}  # Required for the GitHub CLI (`gh`).\n      JOB: ${{ github.job }}\n      WORKFLOW: ${{ github.workflow_ref }}\n    run: |\n      # Download the ghasum CLI\n      ARTIFACT=\"ghasum_darwin_arm64.tar.gz\"\n      gh release download \"${VERSION}\" --repo chains-project/ghasum --pattern \"${ARTIFACT}\"\n      echo \"${CHECKSUM}  ${ARTIFACT}\" | shasum -a 512 -c -\n      tar -xf \"${ARTIFACT}\"\n\n      # Verify the action checksums\n      WORKFLOW=$(echo \"${WORKFLOW}\" | cut -d '@' -f 1 | cut -d '/' -f 3-5)\n      ./ghasum verify -cache /Users/runner/work/_actions -no-evict -offline \"${WORKFLOW}:${JOB}\"\n\n  # The rest of your job ...\n```\n\nFor older Intel-based runners:\n\n```yaml\njob:\n  runs-on: macos-13\n  steps:\n  # The repository has to be checked out before verifying checksums because it\n  #  requires access to the content in .github/workflows. Because this action is\n  #  run before the checksums are verified it should be pinned to a commit SHA.\n  - name: Checkout repository\n    uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2\n\n  # Verify the action checksums with ghasum.\n  - name: Verify action checksums\n    env:\n      VERSION: vX.Y.Z                # Set the ghasum version.\n      CHECKSUM: 3414193...           # Set the ghasum binary checksum.\n      GH_TOKEN: ${{ github.token }}  # Required for the GitHub CLI (`gh`).\n      JOB: ${{ github.job }}\n      WORKFLOW: ${{ github.workflow_ref }}\n    run: |\n      # Download the ghasum CLI\n      ARTIFACT=\"ghasum_darwin_amd64.tar.gz\"\n      gh release download \"${VERSION}\" --repo chains-project/ghasum --pattern \"${ARTIFACT}\"\n      echo \"${CHECKSUM}  ${ARTIFACT}\" | shasum -a 512 -c -\n      tar -xf \"${ARTIFACT}\"\n\n      # Verify the action checksums\n      WORKFLOW=$(echo \"${WORKFLOW}\" | cut -d '@' -f 1 | cut -d '/' -f 3-5)\n      ./ghasum verify -cache /Users/runner/work/_actions -no-evict -offline \"${WORKFLOW}:${JOB}\"\n\n  # The rest of your job ...\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eFor Windows runners\u003c/summary\u003e\n\n```yaml\njob:\n  runs-on: windows-2025 # Also 'windows-latest'\n  steps:\n  # The repository has to be checked out before verifying checksums because it\n  #  requires access to the content in .github/workflows. Because this action is\n  #  run before the checksums are verified it should be pinned to a commit SHA.\n  - name: Checkout repository\n    uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2\n\n  # Verify the action checksums with ghasum.\n  - name: Verify action checksums\n    env:\n      VERSION: vX.Y.Z                # Set the ghasum version.\n      CHECKSUM: e3d49db...           # Set the ghasum binary checksum.\n      GH_TOKEN: ${{ github.token }}  # Required for the GitHub CLI (`gh`).\n      JOB: ${{ github.job }}\n      WORKFLOW: ${{ github.workflow_ref }}\n    run: |\n      # Download the ghasum CLI\n      $ARTIFACT = \"ghasum_windows_amd64.zip\"\n      gh release download \"$env:VERSION\" --repo chains-project/ghasum --pattern \"$ARTIFACT\"\n      if ((Get-FileHash -Algorithm SHA512 \"$ARTIFACT\").Hash -ne $env:CHECKSUM) {\n          Write-Error \"Checksum mismatch!\"\n          exit 1\n      }\n      Expand-Archive -Path \"$ARTIFACT\" -DestinationPath .\n\n      # Verify the action checksums\n      $WorkflowParts = $env:WORKFLOW -split '@'\n      $WorkflowPath = ($WorkflowParts[0] -split '/')[2..4] -join '/'\n      .\\ghasum.exe verify -cache C:\\a\\_actions -no-evict -offline \"${WorkflowPath}:${env:JOB}\"\n\n  # The rest of your job ...\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eFor ARM-based Ubuntu runners\u003c/summary\u003e\n\n```yaml\njob:\n  runs-on: ubuntu-24.04-arm\n  steps:\n  # The repository has to be checked out before verifying checksums because it\n  #  requires access to the content in .github/workflows. Because this action is\n  #  run before the checksums are verified it should be pinned to a commit SHA.\n  - name: Checkout repository\n    uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2\n\n  # Verify the action checksums with ghasum.\n  - name: Verify action checksums\n    env:\n      VERSION: vX.Y.Z                # Set the ghasum version.\n      CHECKSUM: 8a5c3d8...           # Set the ghasum binary checksum.\n      GH_TOKEN: ${{ github.token }}  # Required for the GitHub CLI (`gh`).\n      JOB: ${{ github.job }}\n      WORKFLOW: ${{ github.workflow_ref }}\n    run: |\n      # Download the ghasum CLI\n      ARTIFACT=\"ghasum_linux_arm64.tar.gz\"\n      gh release download \"${VERSION}\" --repo chains-project/ghasum --pattern \"${ARTIFACT}\"\n      echo \"${CHECKSUM}  ${ARTIFACT}\" | shasum -a 512 -c -\n      tar -xf \"${ARTIFACT}\"\n\n      # Verify the action checksums\n      WORKFLOW=$(echo \"${WORKFLOW}\" | cut -d '@' -f 1 | cut -d '/' -f 3-5)\n      ./ghasum verify -cache /home/runner/work/_actions -no-evict -offline \"${WORKFLOW}:${JOB}\"\n\n  # The rest of your job ...\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eFor ARM-based Windows runners\u003c/summary\u003e\n\n```yaml\njob:\n  runs-on: windows-11-arm\n  steps:\n  # The repository has to be checked out before verifying checksums because it\n  #  requires access to the content in .github/workflows. Because this action is\n  #  run before the checksums are verified it should be pinned to a commit SHA.\n  - name: Checkout repository\n    uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2\n\n  # Verify the action checksums with ghasum.\n  - name: Verify action checksums\n    env:\n      VERSION: vX.Y.Z                # Set the ghasum version.\n      CHECKSUM: 3114a13...           # Set the ghasum binary checksum.\n      GH_TOKEN: ${{ github.token }}  # Required for the GitHub CLI (`gh`).\n      JOB: ${{ github.job }}\n      WORKFLOW: ${{ github.workflow_ref }}\n    run: |\n      # Download the ghasum CLI\n      $ARTIFACT = \"ghasum_windows_arm64.zip\"\n      gh release download \"$env:VERSION\" --repo chains-project/ghasum --pattern \"$ARTIFACT\"\n      if ((Get-FileHash -Algorithm SHA512 \"$ARTIFACT\").Hash -ne $env:CHECKSUM) {\n          Write-Error \"Checksum mismatch!\"\n          exit 1\n      }\n      Expand-Archive -Path \"$ARTIFACT\" -DestinationPath .\n\n      # Verify the action checksums\n      $WorkflowParts = $env:WORKFLOW -split '@'\n      $WorkflowPath = ($WorkflowParts[0] -split '/')[2..4] -join '/'\n      .\\ghasum.exe verify -cache C:\\a\\_actions -no-evict -offline \"${WorkflowPath}:${env:JOB}\"\n\n  # The rest of your job ...\n```\n\n\u003c/details\u003e\n\n### Using Go\n\nIn a Go-based project, you can use the Go toolchain to integrate `ghasum`. To\nget started, add `ghasum` as a tool dependency:\n\n```shell\ngo get -tool github.com/chains-project/ghasum/cmd/ghasum\n```\n\nInitialize `ghasum` for your project if you haven't already:\n\n```shell\ngo run github.com/chains-project/ghasum/cmd/ghasum init\n```\n\nVerify the setup succeeded:\n\n```shell\ngo run github.com/chains-project/ghasum/cmd/ghasum verify\n```\n\nAnd update your workflows to verify the checksums at runtime. You can follow\neither the Local Action or Inline approach. Like with the other approaches you\nmust first use `actions/checkout`. Moreover, because this runs from source you\nmust also first use `actions/setup-go`. Both should be pinned to a commit SHA as\nthey're run before checksum verification.\n\n\u003cdetails\u003e\n\n\u003csummary\u003eFor Ubuntu/macOS runners\u003c/summary\u003e\n\n```yaml\n- uses: actions/checkout # @commit-sha\n- uses: actions/setup-go # @commit-sha\n- name: Verify action checksums\n  env:\n    JOB: ${{ github.job }}\n    WORKFLOW: ${{ github.workflow_ref }}\n  run: |\n    WORKFLOW=$(echo \"${WORKFLOW}\" | cut -d '@' -f 1 | cut -d '/' -f 3-5)\n    go run github.com/chains-project/ghasum/cmd/ghasum verify \\\n      -cache /home/runner/work/_actions -no-evict -offline \"${WORKFLOW}:${JOB}\"\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\n\u003csummary\u003eFor Windows runners\u003c/summary\u003e\n\n```yaml\n- uses: actions/checkout # @commit-sha\n- uses: actions/setup-go # @commit-sha\n- name: Verify action checksums\n  env:\n    JOB: ${{ github.job }}\n    WORKFLOW: ${{ github.workflow_ref }}\n  run: |\n    $WorkflowParts = $env:WORKFLOW -split '@'\n    $WorkflowPath = ($WorkflowParts[0] -split '/')[2..4] -join '/'\n    go run github.com/chains-project/ghasum/cmd/ghasum verify \\\n      -cache C:\\a\\_actions -no-evict -offline \"${WorkflowPath}:${env:JOB}\"\n```\n\n\u003c/details\u003e\n\n## Recommendations\n\nWhen using ghasum it is recommended to pin all Actions to version tags. If\nActions are benign, these won't change over time. Major version tags or branch\nrefs are expected to change over time as changes are made to the Action, which\nresults in failing verification by ghasum. Commit SHAs do not have to be used\nbecause the benefits they provide are covered by ghasum.\n\nIf an Action misbehaves - moving version refs after publishing - it is\nrecommended to use commit SHAs instead to avoid failing verification by ghasum.\n\n```yaml\n# Recommended: exact version tags\n- uses: actions/checkout@v4.1.1\n\n# Possible alternative: commit SHAs\n- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1\n\n# Discouraged: major version refs\n- uses: actions/checkout@v4\n\n# Discouraged: branches\n- uses: actions/checkout@main\n```\n\n## Benefits\n\n- Pins transitive (composite) GitHub Actions.\n- Prevents using actions that have changed since you started using them. Avoids\n  the impact of supply chain attacks such as [CVE-2025-30066] (`tj-actions`).\n- Prevents using [impostor commits].\n- Reveals your GitHub Actions dependency hierarchy with `ghasum list`, even\n  without integrating `ghasum`.\n- Protects against git commit SHA hash collisions (more details below).\n\nSome of these limitations are addressed by [immutable releases], however it is\ncostly to verify the actions you use consistently use them and relies on GitHub\nenforcing rules rather than cryptography.\n\n[immutable releases]: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases\n[impostor commits]: https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd\n[CVE-2025-30066]: https://github.com/advisories/GHSA-mrrh-fwg8-r2c3\n\n## Limitations\n\n- Requires manual intervention when an Action is updated.\n- The hashing algorithm used for checksums is not (yet, [#5]) configurable.\n- Docker-based [unpinnable actions] are not (yet, [#216]) supported.\n- Checksums do not provide protection against code-based [unpinnable actions].\n- Checksums cannot be enforced for the [pre] scripts of actions.\n\n[#5]: https://github.com/chains-project/ghasum/issues/5\n[#216]: https://github.com/chains-project/ghasum/issues/216\n[unpinnable actions]: https://www.paloaltonetworks.com/blog/prisma-cloud/unpinnable-actions-github-security/\n[pre]: https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#runspre\n\n## Background\n\nThe dependency ecosystem for GitHub Actions is fully reliant on git. The version\nof an Action to use is specified using a git ref (branch or tag) or commit SHA.\nGit refs provide no integrity guarantees. And while commit SHAs do provide some\nintegrity guarantees, since they're based on the older SHA1 hash the guarantees\nare not optimal.\n\nBesides being older and having better, modern algorithms available, SHA1 is\nvulnerable to attacks, including [SHAttered] and [SHAmbles]. This means it is\npossible for a motivated and well-funded adversary to mount an attack on the\nGitHub Actions ecosystem. Note that GitHub does have [protections in place] to\ndetect such attacks, but from what is publicly available this is limited to the\n[SHAttered] attack.\n\nThis project is a response to that theoretical attack - providing a way to get,\nrecord, and validate checksums for GitHub Actions dependencies using a more\nsecure hashing algorithm. As an added benefit, it can also be used as an\nalternative to in-workflow commit SHA.\n\n[protections in place]: https://github.blog/2017-03-20-sha-1-collision-detection-on-github-com/\n[shattered]: https://shattered.io/\n[shambles]: https://sha-mbles.github.io/\n\n### Git's hash function transition\n\nThe Git project has a [hash function transition] objective with the goal of\nmigrating from SHA-1 to SHA-256. This discussion was started around the time of\nthe SHAttered attack and has gradually been developed over time but is, as of\nwriting, still experimental. The transition would eliminate the need for this\nproject from a security perspective, but it could remain useful due to its other\nperks.\n\n[hash function transition]: https://git-scm.com/docs/hash-function-transition\n\n## License\n\nThis software is available under the Apache License 2.0 license, see [LICENSE]\nfor the full license text. The contents of documentation are licensed under the\n[CC BY 4.0] license.\n\n[cc by 4.0]: https://creativecommons.org/licenses/by/4.0/\n[LICENSE]: ./LICENSE\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchains-project%2Fghasum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchains-project%2Fghasum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchains-project%2Fghasum/lists"}