← Back to Plugins
Tools

Secure Plugin Installer

OrionAIDev By OrionAIDev 👁 114 views ▲ 0 votes

Audit and gate third-party Claude Code plugins / OpenClaw skills before enabling them: capability enumeration, categorised pattern scanning, commit pinning, hash-chained trust ledger, per-MCP-server approval.

GitHub

Install

pip install skillspector`

README

# Secure Plugin Installer

Cross-platform skill for auditing and gating third-party packages —
**Claude Code plugins** (sourced from GitHub or any git-clonable URL) and
**OpenClaw / ClawHub skills** (typically installed as plain directories
under `/opt/<env>/workspace/skills/`).

This document is the **comprehensive reference** for humans. The
companion [`SKILL.md`](SKILL.md) is a compact agent-facing trigger that
describes the workflow at a high level; agents (Claude Code, OpenClaw,
etc.) read it to decide when and how to invoke the installer. If
something is brief in SKILL.md, the long-form explanation lives here.

---

## Contents

1. [What this is](#what-this-is)
2. [When this is invoked](#when-this-is-invoked)
3. [Quickstart (end-user examples)](#quickstart-end-user-examples)
4. [What "install" means in each profile](#what-install-means-in-each-profile)
5. [The 6-step workflow](#the-6-step-workflow)
6. [Trust ledger](#trust-ledger)
7. [Threat model — what this catches and doesn't](#threat-model)
8. [Architecture](#architecture)
9. [Required dependencies](#required-dependencies)
10. [Install destinations and workspace layout](#install-destinations-and-workspace-layout)
11. [Backup, rollback, version comparison, and collision policy](#backup-rollback-and-collision-policy)
12. [Operational notes](#operational-notes)
13. [Known limitations and open work](#known-limitations-and-open-work)

---

## What this is

A guarded install pipeline for third-party packages whose code will run
inside your agent's privileges (Claude Code or OpenClaw). Five layers,
each independently useful:

| Layer | What it does | Stops |
|---|---|---|
| **Hardened clone** | `git -c core.symlinks=false clone --depth=1 --no-tags --no-hardlinks` | Filesystem-traversal attacks via malicious symlinks; pollution of source repos via hardlinks |
| **Capability enumeration** | Parses declared hooks / MCP servers / postinstall scripts / permissions / build steps | Surfaces every auto-executing or privilege-granting declaration |
| **Categorised pattern scan** | 7 risk classes × ~40 detectors, severity-aware, location-demoted (docs/tests are MEDIUM→LOW) | Surfaces command-exec, network, encoded-payload, destructive, persistence, exfil, credential-access tells |
| **Trust ledger** | Append-only, SHA-256 hash-chained log of inspections and approvals; pins commit SHAs and marketplace sources | Tamper-detected if an entry is edited; SHA drift forces re-inspection; marketplace-source drift invalidates approvals |
| **Typed-confirmation install gate** | Demands the user type the exact slug back, plus a separate typed confirmation per declared MCP server | Rubber-stamp / accidental approvals |

There's also a **PreToolUse hook** on the claude-code profile that
intercepts `Edit`/`Write` of `settings.json` and blocks additions to
`enabledPlugins` whose slug isn't APPROVED in the trust ledger. The
OpenClaw analog isn't built yet (see [Known limitations](#known-limitations-and-open-work)).

## When this is invoked

Trigger this skill **whenever a user asks to install, audit, or
"security review" a third-party plugin or skill** — Claude Code or
OpenClaw. Skip only for packages you've already approved at the current
SHA / content hash (the trust ledger remembers).

If you ask an agent to install a ClawHub skill on a system where this
is registered, this gated workflow is the default path. If you want to
bypass it for a specific case, say so explicitly.

## Quickstart (end-user examples)

> All examples assume the `secure-plugin-installer` skill lives in your
> environment's skills directory. On Claude Code that's
> `~/.claude/skills/secure-plugin-installer/`; on OpenClaw it's
> `/opt/<env>/workspace/skills/secure-plugin-installer/`.

### Inspect a Claude Code plugin from GitHub

```
python3 scripts/safe_inspect.py everything-claude-code@everything-claude-code
```

(Or use the `.sh` wrapper: `bash scripts/safe_inspect.sh everything-claude-code@everything-claude-code`.)

### Inspect a locally-installed OpenClaw skill (no git history)

```
bash scripts/safe_inspect.sh --local /opt/openclaw-workspace/skills/superpowers --marketplace my-marketplace
```

Falls back to a SHA-256 content hash when no git history is present.
Writes the report to `<workspace>/plugin-inspect/<plugin>/REPORT.md`,
**not** into the source directory.

### Inspect again later (same SHA / same content)

```
bash scripts/safe_inspect.sh everything-claude-code@everything-claude-code
```

Short-circuits with:

```
Prior trust: APPROVED at 2026-05-14T18:13:34Z by alice (same SHA).
*** Already trusted at this SHA — inspection skipped. ***
```

Pass `--force` to re-scan anyway.

### Inspect after an upstream commit (SHA drift)

Same command. Output shows:

```
Prior trust: SHA DIFFERS  (4423f10cfb9e -> 364245445f1f). Prior approval (if any) is INVALID.
--- Diff vs trusted SHA (--stat) ---
README.md | 2 ++
1 file changed, 2 insertions(+)
Pattern scan will be scoped to changed files. Pass --force for a full re-scan.
```

### Approve + install (claude-code profile)

Interactive:

```
python3 scripts/install.py everything-claude-code@everything-claude-code
```

Non-interactive (for automation):

```
python3 scripts/install.py everything-claude-code@everything-claude-code \
    --confirm everything-claude-code@everything-claude-code \
    --confirm-mcp <server1> --confirm-mcp <server2> \
    --approver alice
```

### Roll back

```
python3 scripts/rollback.py everything-claude-code@everything-claude-code
```

Surgically removes the slug from `enabledPlugins` and also removes the
marketplace entry from `extraKnownMarketplaces` if no other plugin
references it. Idempotent. Use `--dry-run` to preview.

### Verify trust-ledger integrity

```
python3 scripts/trust_verify.py
```

Exit 0 if the SHA-256 hash chain is intact; non-zero with the broken
entry index otherwise.

### Inspect every skill in an environment

```
for d in /opt/openclaw-workspace/skills/*/; do
  bash scripts/safe_inspect.sh --force --local "$d" --marketplace my-marketplace 2>&1 |
    grep -E "^Recommendation:"
done
```

Per-skill recommendation, suitable for compliance-style audits.

## What "install" means in each profile

This is one of the bigger conceptual cliffs to be aware of — the two
runtime profiles have different installation models, and the installer
**only fully implements the claude-code model right now**.

### Claude Code profile

- Plugins are **referenced** in `~/.claude/settings.json` under
  `enabledPlugins` (a dict of slug → bool) and `extraKnownMarketplaces`
  (a dict of marketplace-name → source descriptor).
- The plugin **source files** live elsewhere — fetched from the
  marketplace's git source at runtime by Claude Code itself.
- "Install" = add to `enabledPlugins` (+ register marketplace if not
  already registered). That's what `install.py` does.
- "Uninstall" = remove from `enabledPlugins` (+ remove orphaned
  marketplace). That's what `rollback.py` does.
- The inspector clones the source to a workspace location for review
  but **does not copy it anywhere "installed"** — Claude Code does that
  on its own.

### OpenClaw profile

- Skills are **directories** under `/opt/<env>/workspace/skills/`.
- They are auto-loaded by openclaw at session start; there's no
  separate "enabled / disabled" gate analogous to `enabledPlugins`.
- The canonical config at `/opt/openclaw-config/openclaw.json` has
  `skills` and `plugins` top-level keys, but their schema doesn't match
  Claude Code's `enabledPlugins`/`extraKnownMarketplaces`.
- **`install.py` does not currently work as designed on this profile.**
  It looks for `enabledPlugins`/`extraKnownMarketplaces` keys that
  aren't there and fails the marketplace-not-registered precondition.
  See [Known limitations](#known-limitations-and-open-work).
- What still works on OpenClaw:
  - **Inspection** (`safe_inspect.py`) — fully functional. Reads,
    enumerates capabilities, scans patterns, records in trust ledger.
  - **Trust ledger** — written and verified normally. Approvals can be
    recorded directly with `trust.py approve`.
  - **Reporting** — REPORT.md generates correctly.

### OpenClaw install flow

`install.py` is profile-aware (since v1.1.0). On OpenClaw it skips the
settings mutation, confirms the skill is present on disk, and records the
approval in the trust ledger:

1. `safe_inspect.sh --local /opt/<env>/workspace/skills/<name>` — inspect
2. Review the REPORT.md
3. `python3 scripts/install.py <name>@<env> --confirm <name>@<env> --approver <your-name>`
   — typed-confirmation gate, records approval (override the skills dir with
   `--skills-dir` if needed). Recording approval directly with
   `python3 scripts/trust.py approve <name>@<env> <your-name>` remains a valid
   shortcut.
4. The skill is file-system-installed; no settings mutation needed.
5. Restart the env's container (if the skill wasn't there at session start).

## The 6-step workflow

These map directly onto `SKILL.md`'s numbered steps; this section
explains the rationale.

1. **Research.** Identify the package and where it lives. Surface
   provenance signals up front (stars, age, owner type) so the user
   isn't approving blindly.

2. **Inspect.** Clone (or read in-place via `--local`), enumerate
   declared capabilities, run categorised pattern scan, fetch GitHub
   provenance. Write REPORT.md. Record an **inspection** entry in the
   trust ledger for the plugin and each declared MCP server.

3. **Install gate.** Present REPORT.md to the user. The
   **Recommendation** section distills the findings:
   - `MINIMAL RISK SURFACE` — no declared capabilities, no pattern findings
   - `REVIEW RECOMMENDED` — MEDIUM-only findings (pattern scan or the
     optional SkillSpector scanner) or normal capabilities
   - `REQUIRES HUMAN REVIEW` — HIGH pattern findings OR any HIGH
     SkillSpector finding OR auto-executing capabilities (hook, MCP
     server, postinstall) OR broad permission rules (Bash(*), etc.). Pe

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...