Who: owners and/or lead contributors of ALL* Ceph org repos. You can follow this search as a reference.

What: Please check the GitHub workflows in your repos for GH Action deps not pinned to SHA-1 hashes. You can use the following script to scan and fix them (replaces version tags with their corresponding SHA-1 commit hash):

#!/usr/bin/env bash
set -euo pipefail

WORKFLOWS_DIR="${1:-.}/.github/workflows"

echo "Scanning workflows in: $WORKFLOWS_DIR"

# Recursively grep workflow files for actions not pinned to SHA-1
grep -Prno --include="*.y*ml" 'uses:\s*([^/]+)/([^@]+)@([^[:space:]]+)' "${WORKFLOWS_DIR}" | \
  while IFS=: read -r file _line_num uses_line; do
    echo -n "$file - "
    # Extract owner/repo/version
    if [[ "$uses_line" =~ uses:\ ([^/]+)/([^@]+)@([^[:space:]]+) ]]; then
        owner="${BASH_REMATCH[1]}"
        repo="${BASH_REMATCH[2]}"
        version="${BASH_REMATCH[3]}"
        action="$owner/$repo"
        echo -n "$owner/$repo: "
    else
        echo "Failed to parse line: $uses_line [FAIL]"
        continue
    fi

    # Skip if already pinned to SHA
    if [[ "$version" =~ ^[0-9a-f]{40}$ ]]; then
        echo "SHA-1 pinned: $version [OK]"
        continue
    else
        echo -n "Tag pinned: $version [WARNING], "
    fi
    api_url="https://api.github.com/repos/$owner/$repo/git/ref/tags/$version"

    # Get full SHA
    sha=$(curl -s "$api_url" | jq -r '.object.sha')
    if [[ "$sha" == "null" || -z "$sha" ]]; then
        echo "Could not resolve $version [FAIL]"
        continue
    fi

    echo "Replacing $version → $sha [OK]"

    # Precise sed replacement: match 'uses:' literally and append comment
    sed -i.bak "s|uses:\s*$action@$version|uses: $action@$sha # version $version|g" "$file"
done


Sample run with ceph/ceph repo:
$ ./pin-gh-actions.sh .
Scanning workflows in: ./.github/workflows
./.github/workflows/needs-rebase.yml - eps1lon/actions-label-merge-conflict: SHA-1 pinned: b8bf8341285ec9a4567d4318ba474fee998a6919 [OK]
...
./.github/workflows/redmine-upkeep.yml - actions/setup-python: SHA-1 pinned: 42375524e23c412d93fb67b49958b491fce71c38 [OK]
./.github/workflows/qa-symlink.yml - actions/checkout: Tag pinned: v4 [WARNING], Replacing v4 → 08eba0b27e820071cde6df949e0beb9ba4906955 [OK]
./.github/workflows/qa-symlink.yml - actions/checkout: Tag pinned: v4 [WARNING], Replacing v4 → 08eba0b27e820071cde6df949e0beb9ba4906955 [OK
]

Why: SCM attacks are becoming more frequent, and GH Actions ecosystem is regularly targeted. After that episode, we enforced SHA pinning for all non-official Actions, assuming that official GH Actions would be "less vulnerable". Github has recently introduced a setting to force all GH Actions to be pinned to full SHA-1 commit hashes. Given the cost-benefit of using SHA-1 pinning, all Ceph org repos should ensure their GH Actions are SHA-1 pinned.

When: ASAP. Deadline is pending to be discussed/approved by the CSC (tentatively 1 month, end of October). After that, all GH Workflows using tag-pinned Actions would stop working.

* Exceptions: GH workflows are automatically disabled in: archived repos, and repos forked from other projects (ONLY IF the GH Workflows were enabled when the repo was forked).

NOTE 1: SHA-1 pinning only ensures the immutability of that direct dependency; if that dependency in turn relies on other deps through version pinning or direct download, the supply-chain is still vulnerable. That's why for unofficial GH Actions, there's a review process in place required to approve them.

NOTE 2: While SHA-1 is considered cryptographically broken, "preimage resistance" (forgeing some commit that resolves into a given hash) continues being secure.

Kind Regards,

Ernesto Puerta