# How the Security Review Pipeline for Claude Plugins Works: A Technical Deep Dive

> Discover the technical details of the Claude plugin security review pipeline. Learn how schema validation static analysis and AI policy checks ensure marketplace safety.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: deep-dive
- Published: 2026-08-31

---

**The security review pipeline for Claude plugins is a multi-stage CI process that combines deterministic schema validation, nine static security invariants, and AI-powered policy analysis to vet every plugin before it reaches the public marketplace.**

The `anthropics/claude-plugins-community` repository maintains a rigorous automated validation system for its plugin ecosystem. This security review pipeline for Claude plugins validates structural integrity and enforces safety requirements through deterministic GitHub Actions, ensuring that only compliant, secure extensions are published to the marketplace.

## The Three-Stage Architecture

The pipeline is implemented as two complementary composite actions that execute sequentially on every pull request touching the `.claude-plugin/` directory tree.

### Stage 1: Schema and Invariant Validation

The **`validate-plugins`** composite action enforces structural correctness through canonical schema checks and static security invariants. Located in `.github/actions/validate-plugins/`, this action runs the `claude plugin validate` CLI command against the marketplace manifest and enforces rules I1 through I9.

These invariants govern naming conventions, alphabetical sorting, SHA-pinning requirements, URL safety, and shell metacharacter prohibition. The validation logic resides in [`.github/actions/validate-plugins/scripts/11-validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/11-validate-invariants.sh) for rule enforcement and [`.github/actions/validate-plugins/scripts/20-validate-cli-marketplace.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/20-validate-cli-marketplace.sh) for schema validation.

For external plugins, the action clones repositories at their exact pinned `source.sha` into an isolated temporary directory and validates the [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) file without executing any code from the cloned repository.

### Stage 2: Policy and Safety Scanning

The **`scan-plugins`** composite action performs a Claude-based policy review against Anthropic’s Software Directory Policy and Acceptable Use Policy. This action, defined in `.github/actions/scan-plugins/`, launches a headless `claude -p` invocation using the minimal prompt defined in [`.github/actions/scan-plugins/policy/prompt.md`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/scan-plugins/policy/prompt.md).

The scan evaluates the entire plugin payload, including declared surfaces and hidden files, and generates a JSON verdict containing boolean fields such as `passes`, `may_make_external_network_calls`, and `may_download_additional_software`.

Before the LLM review, the action runs a static pin check via [`.github/actions/scan-plugins/lib/pin-check.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/scan-plugins/lib/pin-check.sh) to flag unpinned "auto-exec" servers. This script detects floating package-manager invocations like `npx`, `pipx`, `bunx`, or `uvx` that use `@latest`, version ranges, or omit version specifiers entirely.

### Stage 3: Reporting and Enforcement

Both actions emit results as GitHub annotations using `::warning` and `::error` workflow commands. The `validate-plugins` action generates its final markdown report via [`.github/actions/validate-plugins/scripts/90-report.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/90-report.sh), while `scan-plugins` produces a step-summary table.

Each action outputs structured JSON files indicating `scanned` and `failed` states. The pipeline supports optional job failure through the `fail-on-findings` input parameter, which can be set to `"true"` to block merges when violations are detected.

## Pipeline Execution Flow

### PR Validation Workflow

The [`.github/workflows/validate-plugins.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/workflows/validate-plugins.yml) workflow triggers on pull requests modifying `.claude-plugin/**` paths. It detects changed entries, runs invariant checks I1-I9, validates the marketplace JSON, clones external plugins at their pinned SHAs, and checks auxiliary configuration files including [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json), [`.lsp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.lsp.json), and [`hooks/hooks.json`](https://github.com/anthropics/claude-plugins-community/blob/main/hooks/hooks.json).

```yaml

# .github/workflows/validate-plugins.yml

name: Validate Plugins
on:
  pull_request:
    paths:
      - '.claude-plugin/**'
jobs:
  validate:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: anthropics/claude-plugins-community/.github/actions/validate-plugins@<PINNED-SHA>
        with:
          marketplace-path: .claude-plugin/marketplace.json

```

### Security Scan Workflow

Running in parallel or sequentially, [`.github/workflows/scan-plugins.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/workflows/scan-plugins.yml) executes the policy scan. It performs static pin checks, invokes the Claude LLM with the policy prompt, and surfaces violations through GitHub’s annotation system.

```yaml

# .github/workflows/scan-plugins.yml

name: Scan Plugins
on:
  pull_request:
    paths:
      - '.claude-plugin/**'
jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    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 }}
          fail-on-findings: "true"

```

### Nightly Drift Detection

A scheduled workflow, [`validate-plugins-nightly.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/validate-plugins-nightly.yml), runs `validate-plugins` with `validate-all-external: true` to detect deletions or force-pushes that break previously pinned SHAs in the [`.claude-plugin/marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json) manifest.

## Core Security Guarantees

The security review pipeline for Claude plugins enforces several critical protections:

- **No arbitrary code execution**: External plugins are cloned into temporary directories where only the static `claude plugin validate` command runs. No scripts from cloned repositories are executed during validation.
- **SSRF protection**: The system maintains a whitelist of allowed hosts (`github.com`, `gitlab.com`, `bitbucket.org`) and rejects bare IP addresses through the `allowed-hosts` input parameter.
- **Dependency pinning**: The static pin check in [`lib/pin-check.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/lib/pin-check.sh) prevents submission of plugins that invoke package managers without explicit version pins.
- **Credential cross-service detection**: The LLM policy prompt explicitly instructs Claude to flag code that reads credentials belonging to one service and transmits them to a different service.
- **Structural integrity**: Invariants I1-I9 ensure the marketplace data is well-formed, alphabetically sorted, duplicate-free, and that all external sources reference 40-character SHA commits.

## Summary

- The **security review pipeline for Claude plugins** operates as a deterministic, isolated CI process using GitHub Actions.
- **Stage 1** validates schema compliance and enforces nine static security invariants through the `validate-plugins` action.
- **Stage 2** performs AI-powered policy analysis via the `scan-plugins` action, including static pin checks for unpinned executors.
- **Stage 3** surfaces violations as GitHub annotations and markdown reports, with optional `fail-on-findings` enforcement.
- The pipeline prevents code execution from external repositories by cloning only to validate [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) static files.
- Nightly drift detection ensures pinned SHAs remain valid against upstream repository changes.

## Frequently Asked Questions

### What happens if a plugin fails the security review pipeline?

Failed validations surface as GitHub annotations and workflow logs. If `fail-on-findings` is set to `"true"` in the workflow configuration, the CI job fails and blocks the pull request from merging. The [`90-report.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/90-report.sh) script generates a detailed markdown report outlining specific invariant violations or policy breaches.

### How does the pipeline prevent code execution from external repositories?

The `validate-plugins` action clones external repositories into isolated temporary directories and runs only the `claude plugin validate` command against the static [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) file. According to the security model documented in [`.github/actions/validate-plugins/README.md`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/README.md), no scripts, binaries, or install hooks from the cloned repository are executed during the validation process.

### What are the I1-I9 invariants checked during validation?

The nine invariants enforce marketplace data quality and security basics, including alphabetical sorting of entries, uniqueness constraints, valid semantic versioning, 40-character SHA pinning for external sources, URL safety verification, and prohibition of shell metacharacters in plugin names. These rules are implemented in [`.github/actions/validate-plugins/scripts/11-validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/11-validate-invariants.sh).

### How does the policy scan detect potential security risks?

The `scan-plugins` action uses a constrained LLM prompt at [`.github/actions/scan-plugins/policy/prompt.md`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/scan-plugins/policy/prompt.md) to evaluate whether plugin code violates Anthropic’s Software Directory Policy or Acceptable Use Policy. It specifically checks for unauthorized external network calls, additional software downloads, and credential cross-service leakage, returning a structured JSON verdict that the CI pipeline interprets for pass/fail decisions.