How Claude Handles Security for External Plugins with a Zero‑Execution Model
Claude validates external plugins using a zero‑execution model that inspects static metadata without ever running the plugin’s source code, eliminating remote code execution risks while ensuring schema compliance.
The anthropics/claude-plugins-community repository implements a rigorous security boundary for community plugins. Rather than executing arbitrary code from external contributors, Claude’s validation pipeline performs static analysis on repository metadata and manifest files only. This approach ensures that malicious or compromised plugins cannot compromise the validation infrastructure or end‑user systems.
The Zero‑Execution Security Architecture
The foundation of Claude’s plugin security lies in the zero‑execution model enforced by the validation workflow defined in .github/actions/validate-plugins/README.md. The architecture guarantees that no JavaScript, Python, or shell code from external repositories runs during the security check.
The workflow operates through several isolated stages:
- Fresh schema installation – The canonical validation schema is sourced from the
@anthropic-ai/claude-codeZod package, freshly installed on each CI run vianpm i -g @anthropic-ai/claude-code(source L7‑L13). - Pinned SHA cloning – External repositories are cloned at exact commit hashes stored in
.claude-plugin/marketplace.json, preventing supply‑chain attacks via moving tags. - Static manifest validation – Only the
claude plugin validatecommand touches the cloned files, verifying JSON structure against the schema without code execution (source L55‑L63).
Canonical Schema Validation
Every plugin must conform to a strictly defined schema enforced by the Claude CLI. The validation process relies on the Zod‑based schema package rather than user‑provided validation logic.
In .github/actions/validate-plugins/README.md, the CI pipeline installs the authoritative schema package fresh for every run:
# Install the latest Claude CLI (required for validation)
npm i -g @anthropic-ai/claude-code
# Validate a single plugin manifest
claude plugin validate path/to/.claude-plugin/plugin.json
This ensures that the validator always uses the latest security policies defined by Anthropic, independent of any cached or compromised dependencies.
Isolated Repository Cloning at Pinned SHAs
The validation action in .github/actions/validate-plugins/scripts/30-validate-cli-external.sh clones external plugin repositories into temporary directories that are destroyed immediately after validation completes.
The workflow enforces precise version control:
- Extracts the exact SHA from
marketplace.jsonfor each plugin entry. - Clones only that specific commit into an isolated temp directory.
- Performs validation using the static
claude plugin validatecommand. - Deletes the temporary clone directory entirely, leaving no persisted artifacts (source L60‑L63).
This ephemeral cloning strategy ensures that even if a repository contains malicious files, those files exist only momentarily and are never executed.
SSRF Protection and Shell Escaping
Before any git clone operation, the validation pipeline implements strict Server‑Side Request Forgery (SSRF) protections and input sanitization.
The security measures include:
- Host allow‑listing – The host component of
source.urlis verified against an explicit allow‑list containing onlygithub.com,gitlab.com, andbitbucket.org. Bare IP addresses are rejected automatically (source L64‑L66). - Safe string interpolation – All contributor‑controlled strings (
url,repo,sha,path) are validated throughassert_safe_*helper functions, double‑quoted, and passed with--end‑of‑options markers to prevent argument injection (source L66‑L69).
These safeguards ensure that malicious URLs cannot prompt the CI runner to contact internal network resources or execute unintended shell commands.
Handling Skill‑Only Entries with Synthetic Manifests
Some community entries ship as skill‑only plugins with strict: false and no plugin.json manifest. Rather than failing or executing code to generate metadata, the validation action synthesizes a minimal manifest using pure data transformation tools.
Inside .github/actions/validate-plugins/scripts/30-validate-cli-external.sh, the action generates the manifest using jq without invoking any plugin code:
# Inside the action (script 30‑validate-cli-external.sh)
jq -n \
--arg name "$PLUGIN_NAME" \
--arg url "$SOURCE_URL" \
'{name:$name, source:{url:$url}}' > "$TMP_DIR/plugin.json"
claude plugin validate "$TMP_DIR/plugin.json"
The jq -n command constructs JSON from scratch using only shell variables, maintaining the zero‑execution guarantee even for unconventional plugin structures.
Running the Zero‑Execution Validation Workflow
Repository maintainers can enforce these security controls through the official GitHub Action. The workflow must be pinned to a specific SHA to prevent tampering:
# .github/workflows/validate-plugins.yml
name: Validate Plugins
on:
pull_request:
paths:
- '.claude-plugin/**'
- 'plugins/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-plugins-community/.github/actions/validate-plugins@v1 # pinned SHA required
with:
marketplace-path: .claude-plugin/marketplace.json
Additional policy invariants are enforced by .github/actions/validate-plugins/scripts/11-validate-invariants.sh, which applies static security checks (I1‑I9) independent of upstream repository contents. Security reviews for external network calls and credential handling follow the rubric defined in .github/actions/scan-plugins/policy/prompt.md.
Summary
- Zero‑execution validation inspects only static metadata via
claude plugin validate, never running external code. - Pinned SHA cloning at exact commits prevents supply‑chain attacks through mutable tags.
- Temporary isolation ensures cloned repositories exist only during validation and are discarded immediately after.
- SSRF prevention blocks non‑standard hosts and bare IP addresses before any network request.
- Shell‑escaping via
assert_safe_*helpers and--markers prevents command injection ingitoperations. - Synthetic manifests for skill‑only entries use
jqconstruction rather than code execution to maintain schema compliance.
Frequently Asked Questions
What is a zero‑execution model in plugin validation?
A zero‑execution model is a security architecture where the validator inspects static files—such as JSON manifests and repository metadata—without ever running the plugin’s source code. In the anthropics/claude-plugins-community repository, this means the claude plugin validate command checks schema compliance using the @anthropic-ai/claude-code Zod package, while no JavaScript, Python, or shell code from the external repository is executed during the CI pipeline.
How does Claude prevent SSRF attacks during plugin validation?
The validation action implements an explicit host allow‑list that permits cloning only from github.com, gitlab.com, and bitbucket.org. Before executing any git clone command, the pipeline validates the URL host against this list and rejects bare IP addresses entirely. Additionally, all URL components undergo assert_safe_* validation and are passed to git with -- end‑of‑options markers to prevent argument injection attacks.
What happens if a plugin doesn't have a plugin.json manifest?
For entries marked with strict: false that lack a plugin.json, the validation workflow synthesizes a minimal manifest internally. Using only the jq -n command with safely interpolated shell variables, the action constructs a compliant JSON object containing just the name and source URL. This synthetic manifest is then validated normally, preserving the zero‑execution guarantee without requiring the external repository to provide executable code.
How are external plugin repositories isolated during validation?
Each external plugin is cloned into a temporary directory created specifically for that validation run. The action clones the repository at the exact SHA recorded in .claude-plugin/marketplace.json, runs the static validation check, and then immediately deletes the temporary directory. This ephemeral approach ensures no artifacts from external repositories persist on the CI runner, eliminating the risk of persistent compromise.
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 →