# Static Security and Policy Rules Enforced by `validate-invariants.sh` in Claude Plugins

> Discover the static security and policy rules enforced by validate-invariants.sh for Claude plugin submissions, including checks for network calls, secrets, and license compliance.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: how-to-guide
- Published: 2026-08-28

---

**The [`validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/validate-invariants.sh) script performs static analysis to block external network calls, executable scripts, hard-coded secrets, and unsafe system imports while enforcing manifest schema compliance and license standards for Claude plugin submissions.**

The [`validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/validate-invariants.sh) script serves as the primary security gatekeeper in the `anthropics/claude-plugins-community` repository. Integrated within the Validate Plugins GitHub Action defined in [`.github/actions/validate-plugins/action.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/action.yml), this bash utility scans contributed plugin code to enforce mandatory security invariants before community acceptance.

## Core Security Invariants Checked

The script operates by scanning file contents, permission bits, and repository structure. It exits with status `1` immediately upon detecting any violation, failing the CI pipeline.

### Prohibited Network and System Commands

The validator strictly forbids shell commands capable of external network communication or dangerous system operations. Using `grep` and pattern matching against file contents, it detects strings matching:

- **Network utilities**: `curl`, `wget`, `ssh`, `scp`, `netcat`, `nc`, `ftp`
- **Destructive operations**: `rm -rf`, `sudo`, `mkfs`, `dd`
- **Process manipulation**: `kill`, `shutdown`

If detected, the script outputs a diagnostic error message:

```text
❌ Invariant violation: Forbidden command
   File: src/fetch_data.py
   Detected: import subprocess
   Reason: Direct subprocess calls are not allowed.

```

### Executable File Restrictions

The script inspects file mode bits to ensure no script files carry executable permissions. It specifically validates extensions such as `*.sh`, `*.py`, and `*.js`. Any file with the executable bit set triggers a violation:

```text
❌ Invariant violation: Executable file
   File: scripts/setup.sh (mode 0755)
   Reason: Executable scripts are prohibited.

```

Contributors must remove executable flags using `chmod -x` or delete the file entirely before resubmission.

### Secret and Credential Detection

To prevent credential leakage, the script implements pattern matching for common secret formats across the codebase:

- **AWS Access Keys**: Strings beginning with `AKIA`
- **API Tokens**: Patterns like `sk_live_` (Stripe) or strings prefixed with `Bearer `
- **Password indicators**: High-entropy strings matching common password or key conventions

This scan catches both accidental commits and embedded credentials that could compromise the plugin ecosystem.

## Code Sandbox and Dependency Controls

### Disallowed Module Imports

The validator parses import statements to enforce the principle of least privilege. It blocks imports that enable network access or arbitrary system command execution:

- `subprocess` and `os.system` (command execution)
- `socket` (raw network access)
- `requests` and `urllib` (HTTP client libraries)

Plugins must operate within the permitted SDK boundaries rather than making raw system calls.

## Metadata and Policy Compliance

### Manifest Schema Validation

Every plugin must include a [`manifest.json`](https://github.com/anthropics/claude-plugins-community/blob/main/manifest.json) (or [`manifest.yaml`](https://github.com/anthropics/claude-plugins-community/blob/main/manifest.yaml)) with mandatory fields. The script validates the presence and typing of:

- `name`: Plugin identifier
- `description`: Functionality summary
- `author`: Attribution details
- `api`: Claude API compatibility version
- `license`: SPDX-compliant license identifier
- `tags`: Categorical descriptors

Missing required fields produce errors such as:

```text
❌ Invariant violation: Manifest validation
   File: manifest.json
   Missing field: "license"
   Reason: All plugins must declare a supported open-source license.

```

### License and Documentation Standards

The script verifies the presence of an OSI-approved license file (MIT, Apache-2.0, or BSD-3-Clause) and validates that [`README.md`](https://github.com/anthropics/claude-plugins-community/blob/main/README.md) contains required sections including usage instructions, security considerations, and contribution guidelines.

### Resource Limits and CI Safety

**File size restrictions** enforce a 1 MiB maximum per file and total repository size caps to prevent binary bloat. Additionally, the script scans for custom GitHub Actions workflows within the plugin directory to prevent privilege escalation through malicious CI configurations.

## Validation Execution Flow

Located at [`.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), the script executes the following sequence:

1. **File Collection**: Gathers all files respecting `.gitignore` patterns
2. **Pattern Matching**: Runs `grep`, `awk`, and conditional checks against invariant rules
3. **Diagnostic Reporting**: Prints prefixed error messages for each violation
4. **Status Determination**: Returns exit code `0` only when all invariants pass, otherwise `1`

## Summary

- **[`validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/validate-invariants.sh)** enforces security boundaries by prohibiting network utilities, executable scripts, and unsafe imports in Claude plugin code.
- **Secret detection patterns** scan for AWS keys, API tokens, and credential formats to prevent data leakage.
- **Manifest validation** ensures required metadata fields and OSI-compliant licenses are present in every submission.
- **Resource limits** restrict file sizes to 1 MiB while blocking custom CI/CD workflows to maintain sandbox integrity.
- **Non-zero exit codes** immediately fail the Validate Plugins GitHub Action upon any invariant violation.

## Frequently Asked Questions

### What happens if [`validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/validate-invariants.sh) finds a prohibited command like `curl`?

The script prints a diagnostic message specifying the file and detected pattern, then exits with status `1`. This causes the Validate Plugins GitHub Action to report a failure, blocking the pull request from merging until the contributor removes the prohibited command.

### Can I include helper shell scripts in my Claude plugin repository?

No, executable scripts are explicitly prohibited. The script checks file permissions on `*.sh`, `*.py`, and `*.js` files. If any carry the executable bit (e.g., mode `0755`), the validation fails. Remove execution permissions with `chmod -x` or delete the script entirely.

### Which license identifiers does the manifest validation accept?

The validator accepts OSI-approved open-source licenses including **MIT**, **Apache-2.0**, and **BSD-3-Clause**. The license must be declared in [`manifest.json`](https://github.com/anthropics/claude-plugins-community/blob/main/manifest.json) using a valid SPDX identifier, and a corresponding license file must exist in the repository root.

### How does the script prevent plugins from making external network requests?

[`validate-invariants.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/validate-invariants.sh) employs multiple defense layers: it greps for network utility commands (`curl`, `wget`, `nc`), blocks Python imports like `requests` and `socket`, and forbids `subprocess` calls that could spawn network-capable binaries. Combined, these checks ensure plugins operate in a network-free sandbox.