How SHA Pinning Prevents Supply Chain Attacks in Claude Plugins
SHA pinning cryptographically binds Claude plugins to specific git commit hashes, ensuring that only vetted code from an approved list in freeze-shas.txt can execute, thereby blocking malicious commits, tampered releases, and dependency confusion attacks.
Claude plugins distributed through the anthropics/claude-plugins-community repository use a hardened SHA pinning pipeline to defend against software supply chain compromises. By cryptographically binding each plugin manifest to an exact git commit SHA stored in .github/freeze-shas.txt, SHA pinning prevents supply chain attacks that attempt to inject malicious code via compromised dependencies or unreviewed updates. This three-layer validation system ensures that Claude executes only cryptographically verified code that maintainers have explicitly approved.
The Three-Layer SHA Pinning Architecture
The repository's CI/CD pipeline enforces SHA pinning through a strict three-step process that governs how plugin code enters the ecosystem.
Step 1: Pin Management with bump-plugin-shas.yml
The workflow .github/workflows/bump-plugin-shas.yml automates the update of trusted commit references. On every push, this workflow reads the curated list of allowed SHAs from .github/freeze-shas.txt and updates each plugin's manifest with the new, verified hash using the ./scripts/bump-shas.sh utility.
This automated management ensures that only commits vetted and added to the freeze list are ever referenced. An attacker cannot simply push a malicious commit to a plugin repository because the CI system will not rewrite the manifest to point to an unapproved SHA.
Step 2: Validation via scan-plugins Action
Within the .github/actions/scan-plugins directory, the test-pin-check.sh script performs rigorous validation of every plugin manifest. The script parses each .claude-plugin/plugin.json file and verifies that the sha field matches an entry in freeze-shas.txt.
If any plugin references a SHA not present in the trusted list, the validation job fails immediately. This check blocks malicious pull requests that attempt to slip unauthorized code into the repository by referencing unvetted commits.
Step 3: Enforcement through validate-plugins.yml
The central workflow .github/workflows/validate-plugins.yml serves as the final gate before any code reaches the main branch or marketplace. This workflow gates every merge on the result of the pin-check, ensuring that only cryptographically verified plugins are published.
Because this enforcement mechanism protects the freeze-shas.txt file itself—requiring code-owner review and CI signing—an attacker would need to compromise the entire governance structure to inject a malicious SHA, making supply chain attacks computationally infeasible.
Cryptographic Integrity Against Common Attack Vectors
SHA pinning creates a deterministic guarantee that the binary Claude executes matches a known-good state. Because the SHA is a cryptographic hash of the entire repository tree, any alteration—even a single character—produces a completely different hash that instantly breaks the pin.
This mechanism specifically mitigates:
- Dependency confusion attacks, where malicious packages mimic legitimate plugin names
- Tampered releases, where build artifacts are modified post-compilation
- Malicious PRs, where contributors attempt to hide backdoors in seemingly benign updates
When the CI pipeline detects a SHA mismatch, it fails before the code reaches execution, effectively neutralizing the threat.
Implementing SHA Pinning in Practice
Each plugin declares its pinned commit in the manifest file located at .claude-plugin/plugin.json:
{
"name": "quickdesign",
"version": "1.3.0",
"sha": "a727be1c7bd6064419b6f60d71993a19198adc17",
"entrypoint": "quickdesign/main.py",
"description": "AI-assisted video design"
}
The automation workflow handles bulk updates through .github/workflows/bump-plugin-shas.yml:
jobs:
bump-shas:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Freeze-shas handling
run: |
# Read the list of pinned SHAs
list=$(cat .github/freeze-shas.txt)
# For each plugin, replace the old SHA with the new one
./scripts/bump-shas.sh "$list"
Validation occurs through the scan-plugins action:
#!/usr/bin/env bash
set -euo pipefail
# Load allowed SHAs
mapfile -t ALLOWED < .github/freeze-shas.txt
# Scan every plugin manifest
for manifest in **/.claude-plugin/plugin.json; do
SHA=$(jq -r .sha "$manifest")
if [[ ! " ${ALLOWED[*]} " =~ " $SHA " ]]; then
echo "✗ $manifest contains unpinned SHA $SHA"
exit 1
fi
done
echo "✓ All plugin SHAs are correctly pinned"
Summary
- SHA pinning in the
anthropics/claude-plugins-communityrepository cryptographically binds plugin execution to specific, vetted git commits. - The three-step pipeline—managed by
bump-plugin-shas.yml, enforced byvalidate-plugins.yml, and verified bytest-pin-check.sh—ensures only approved code reaches production. - The freeze-shas.txt whitelist serves as the single source of truth for acceptable commit hashes, protected by code-owner reviews and CI signing.
- Any code modification changes the repository hash, causing an immediate CI failure that prevents supply chain attacks before they can execute.
Frequently Asked Questions
What happens if a plugin developer pushes a new commit?
The CI pipeline will not automatically adopt the new commit. A maintainer must first verify the code, add the new SHA to .github/freeze-shas.txt, and then trigger the bump-plugin-shas.yml workflow to update the plugin manifest. Until this manual review occurs, Claude continues using the previously pinned, trusted version.
Can an attacker bypass SHA pinning by modifying the plugin.json file directly?
No. The test-pin-check.sh script in the scan-plugins action parses every .claude-plugin/plugin.json file and validates the SHA against the freeze-shas.txt whitelist. If an attacker modifies the manifest to reference a malicious commit, the SHA will not appear in the approved list, causing the validate-plugins.yml check to fail and blocking the merge.
How does SHA pinning protect against dependency confusion attacks?
By pinning the exact commit SHA rather than trusting version tags or package names, Claude ensures it fetches the specific code from the correct repository. An attacker publishing a malicious package with the same name to a public registry cannot influence the installation because Claude validates the cryptographic hash of the actual repository content, not just the package identifier.
What is the role of freeze-shas.txt in the security model?
The freeze-shas.txt file acts as the centralized source of truth for all trusted plugin versions. Protected by repository code-owner rules and cryptographic signing in CI, this file contains the exhaustive list of commit hashes that the system considers safe. The validation scripts treat any SHA not present in this file as untrusted, effectively creating a software bill of materials (SBOM) that gates every plugin deployment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →