What Automated Security Checks Do Claude Plugins Undergo? A Technical Deep Dive
Claude plugins undergo a multi-stage automated security pipeline including static invariant checks (I1-I9), schema validation, SSRF-protected external repo cloning, and AI-driven policy scanning before marketplace publication.
The anthropics/claude-plugins-community repository enforces rigorous automated security checks on every plugin submission through a defense-in-depth CI/CD pipeline. Before any plugin appears in the Claude Marketplace, it must pass two specialized GitHub Actions that validate static constraints, verify cryptographic pinning, and perform automated safety reviews against public policies.
The Two-Stage Security Pipeline
The repository implements automated security checks through two distinct GitHub Actions that execute sequentially on every pull request.
Stage 1: Static Validation with validate-plugins
The validate-plugins composite action serves as the first line of defense, executing nine critical static invariants (I1-I9) documented in .github/actions/validate-plugins/README.md. These invariants enforce marketplace-wide constraints including alphabetical sorting, duplicate name detection, description length limits, HTTPS-only URLs, and 40-character lowercase SHA pinning to prevent supply chain attacks.
For external plugins, the action clones repositories at the specific pinned SHA—verifying the SHA format conforms to I5's requirement for exactly 40-character hexadecimal strings—and runs claude plugin validate against the cloned manifest without executing untrusted code. The system implements an SSRF allow-list restricting network calls to github.com, gitlab.com, and bitbucket.org, and validates all contributor-controlled values (url, repo, sha, path) in .github/actions/validate-plugins/scripts/11-validate-invariants.sh before any shell interaction occurs.
The action also validates the full marketplace file against the canonical Zod schema from @anthropic-ai/claude-code, ensuring structural compliance before any policy scanning begins.
Stage 2: Policy Scanning with scan-plugins
The scan-plugins action performs a Claude-based safety review using the minimal policy prompt defined in .github/actions/scan-plugins/policy/prompt.md, referencing the public Software Directory Policy and Acceptable Use Policy. This AI-driven scan returns a pass/fail verdict and emits ::warning annotations (or ::error when fail-on-findings is enabled), summarizing results in a step-summary table.
Additionally, the static pin check in .github/actions/scan-plugins/lib/pin-check.sh flags floating package manager specifications like @latest or version ranges that could introduce unpinned code execution. The action runs with minimal permissions—restricted to contents: read and optional id-token: write—and limits network calls to allowed hosts for stronger isolation.
Defense-in-Depth Security Layers
The automated security checks operate across multiple defensive layers to ensure comprehensive vetting:
| Layer | What It Checks | Implementation Location |
|---|---|---|
| Static Invariants | I1-I9: alphabetical sorting, duplicates, HTTPS enforcement, SHA pinning, filename consistency, no shell metacharacters | validate-plugins step 11 (.github/actions/validate-plugins/scripts/11-validate-invariants.sh) |
| Schema Validation | Zod schema compliance via claude plugin validate |
validate-plugins step 20 |
| External Validation | Pinned SHA cloning, SSRF guards, re-validation of contributor inputs | validate-plugins step 30 |
| Policy Scan | Claude safety review against public policies; floating specification detection | scan-plugins steps 1-5 |
| Isolation | Read-only job permissions, restricted network hosts | Both actions via permissions blocks |
Running the Security Checks Locally and in CI
To mirror the CI validation pipeline locally, execute the validation scripts in sequence:
export ACTION_PATH=.github/actions/validate-plugins
export VALIDATE_TMP=/tmp/validate-plugins
export BASE_REF=origin/main
export MARKETPLACE_PATH=.claude-plugin/marketplace.json
export ALLOWED_HOSTS="github.com gitlab.com bitbucket.org"
mkdir -p "$VALIDATE_TMP"
bash $ACTION_PATH/scripts/00-detect-changes.sh
bash $ACTION_PATH/scripts/11-validate-invariants.sh # static I1–I9 checks
bash $ACTION_PATH/scripts/20-validate-cli-marketplace.sh
bash $ACTION_PATH/scripts/30-validate-cli-external.sh # clone + validate external plugins
bash $ACTION_PATH/scripts/40-validate-cli-local.sh # validate in-repo plugins
bash $ACTION_PATH/scripts/41-validate-aux-files.sh
bash $ACTION_PATH/scripts/90-report.sh
To integrate the policy scan into your GitHub workflow:
name: Scan Plugins
on:
pull_request:
paths:
- '.claude-plugin/**'
jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # only needed for WIF auth
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: anthropics/claude-plugins-community/.github/actions/scan-plugins@<PINNED-SHA>
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
# Uncomment to block on any finding:
# fail-on-findings: "true"
Key Source Files and Their Roles
.github/actions/validate-plugins/README.md- Documents static invariants I1-I9 and the overall validation flow.github/actions/validate-plugins/scripts/11-validate-invariants.sh- Implements the I1-I9 checks programmatically.github/actions/scan-plugins/README.md- Describes the Claude-based policy scan and static pin check functionality.github/actions/scan-plugins/policy/prompt.md- The minimal policy prompt fed to Claude for safety review verdicts.github/actions/scan-plugins/lib/pin-check.sh- Performs static analysis to flag floating package manager specifications
Summary
- The
anthropics/claude-plugins-communityrepository implements automated security checks through two GitHub Actions:validate-pluginsandscan-plugins. - Static invariants (I1-I9) enforce marketplace constraints including HTTPS-only URLs, 40-character SHA pinning, and prohibition of shell metacharacters in contributor inputs.
- External plugin validation clones repositories at cryptographically pinned SHAs with SSRF protection restricted to
github.com,gitlab.com, andbitbucket.org. - AI policy scanning uses Claude to review submissions against public safety policies while the static pin check detects unpinned dependencies like
@latest. - All checks run with minimal permissions and can be executed locally using the provided shell scripts or integrated into CI pipelines.
Frequently Asked Questions
What are the nine static invariants (I1-I9) checked during validation?
The invariants enforce alphabetical sorting of entries, duplicate name detection, description length limits, HTTPS-only URL requirements, SHA pinning verification (I5 specifically requires 40-character lowercase hex), filename-name consistency, prohibition of direct edits to marketplace.json, vendored path existence validation, and prevention of shell metacharacters in contributor-controlled values.
How does the system prevent SSRF attacks during external plugin validation?
The validate-plugins action restricts network calls to an SSRF allow-list containing only github.com, gitlab.com, and bitbucket.org. It validates all contributor-controlled values (url, repo, sha, path) before any shell interaction or network request occurs, ensuring no requests reach unauthorized internal or external endpoints.
What happens if a plugin fails the AI policy scan?
By default, the scan-plugins action emits ::warning annotations and allows the workflow to continue. When fail-on-findings is set to "true", the action emits ::error annotations and fails the CI check, preventing the plugin from reaching the marketplace until the safety issues are resolved.
Can developers run these automated security checks locally before submitting?
Yes. Developers can execute the same validation scripts used in CI by setting the required environment variables (ACTION_PATH, VALIDATE_TMP, BASE_REF, MARKETPLACE_PATH, ALLOWED_HOSTS) and running the numbered scripts in .github/actions/validate-plugins/scripts/ to perform I1-I9 invariant checks, schema validation, and external repo verification locally.
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 →