Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ Machine-readable JSON Schemas (editor validation for the JSON in this repo; Clau
plugin via `${CLAUDE_PLUGIN_ROOT}`; persist state in `${CLAUDE_PLUGIN_DATA}`. No `../` reach-outs.
- **No PII / secrets.** Public repo + permanent git history: scrub before the first commit, not after.
- **Versioned.** Set an explicit semver `version` in each `plugin.json` so consumers update on bumps.
- **Security-reviewed.** Every plugin clears the playbook's plugin-acceptance security review before publish —
code execution, remote MCP servers, config secrets, cache isolation, data egress, and third-party trust.
Deny by default on unjustified egress or trust delegation.

## Process

The full design charter, extensibility model, plugin-form caveats, and per-plugin migration gate live
in [`docs/MIGRATION-PLAYBOOK.md`](docs/MIGRATION-PLAYBOOK.md). Follow it for every migration.
The full design charter, extensibility model, plugin-form caveats, per-plugin migration gate, and the
plugin-acceptance security review live in [`docs/MIGRATION-PLAYBOOK.md`](docs/MIGRATION-PLAYBOOK.md). Follow it
for every migration.
27 changes: 27 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Security Policy

This marketplace distributes plugins — skills, hooks, and agents — that run code on a consumer's machine and
can wire Claude Code to external systems. Security reports about a published plugin, the marketplace catalog, or
this repository's own tooling are all in scope.

## Reporting a Vulnerability

Please do **not** report security vulnerabilities through public GitHub issues, discussions, or pull requests.

Report them privately through GitHub's [private vulnerability reporting](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability):

1. Open the **Security** tab of this repository.
2. Click **Report a vulnerability** and complete the advisory form.

If private reporting is not available, email **<security@melodicsoftware.com>** instead.

Please include enough detail to reproduce and assess the issue: the affected plugin and version (from its
`plugin.json`), the impact, and reproduction steps. If the report concerns a plugin that executes code (a hook)
or connects to a remote MCP server, note the specific command, endpoint, or data flow involved. We will
acknowledge your report and keep you informed as we investigate and address it.

## Supported Versions

Fixes are applied to the latest released version of each plugin on the default branch; consumers receive them by
updating the marketplace (a plugin delivers a change only on a `version` bump in its `plugin.json`). Older plugin
versions are not maintained.
41 changes: 41 additions & 0 deletions docs/MIGRATION-PLAYBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,47 @@ For each skill/hook/agent being migrated:
2026-06-23). Then run `claude plugin validate --strict <repo-root>` to validate the **catalog manifest
itself** — a bad entry surfaces only there, not in per-plugin validation. Document the plugin in the README.

## Plugin-acceptance security review

A plugin runs code on the consumer's machine and can wire Claude to external systems. **Every plugin accepted
here — new, or a version bump that adds a trust surface — passes this review** in addition to the migration
gate above (whose step 6 gates PII/secrets). **Deny by default** any surface below that can't be justified.
Facts verified against the plugins/MCP reference 2026-07-09; re-verify per the `CLAUDE.md` fresh-docs mandate.

1. **Code execution — hooks & scripts.** A hook command runs shell on the consumer's machine on matched events,
with `${CLAUDE_PLUGIN_ROOT}`, `${CLAUDE_PROJECT_DIR}`, `${CLAUDE_PLUGIN_DATA}`, `${user_config.*}`, and any
`${ENV_VAR}` interpolated in. Check: which binaries it spawns; whether it mutates files in place and is
**advisory** (exits 0, never blocks) vs gating; no `eval` / `curl … | sh` / outbound network; untrusted
input (file contents, tool args, PR/issue text) never flows unquoted into a shell; a kill switch
(`HOOK_<PLUGIN>_ENABLED`) exists.
2. **Remote MCP servers — `.mcp.json` / inline in `plugin.json`.** **Net-new surface** — no current plugin
ships one. A plugin's MCP server **starts automatically when the plugin is enabled** (subject to per-server
approval). Check: the server host/URL and who runs it (first-party vs a third party you're delegating trust
to); transport (local `stdio` vs remote `http`/`sse`/`ws`); **what data leaves the machine** — a remote
server receives whatever Claude sends and, if it returns external content, is a prompt-injection vector
(official guidance: "Verify you trust each server before connecting it"); auth shape (header/Bearer/OAuth)
with any token sourced from `userConfig` `sensitive` or an env var, **never hardcoded**; a stated reason the
capability can't be a local `stdio` server. **Do not accept a third-party remote MCP server** without an
explicit recorded trust decision naming the vendor, the data egress, and the token scope.
3. **Consumer config — `userConfig`.** Any credential/token option MUST set `"sensitive": true` — that masks
input and stores the value in the system keychain (or `~/.claude/.credentials.json`), **not** `settings.json`.
Non-sensitive values land in `settings.json` under `pluginConfigs[<id>].options` and are readable — never put
a secret there. Endpoints and toggles are fine as non-sensitive. Every option is documented.
4. **Cache isolation — no reach-outs.** References only files inside the plugin via `${CLAUDE_PLUGIN_ROOT}`;
persists state in `${CLAUDE_PLUGIN_DATA}`. No `../` reach-outs, no absolute paths, no reading consumer files
outside `${CLAUDE_PROJECT_DIR}`.
5. **Data egress — telemetry & network.** Any telemetry (e.g. `HOOK_TELEMETRY_SINK`) is opt-in (unset = exact
no-op), never writes to the hook's stdout/`additionalContext` channel, and emits only the declared envelope —
no payload beyond the documented schema. Name any other outbound network call and justify it.
6. **Provenance & third-party trust.** Verify authorship (does `plugin.json` `author` match who actually
submitted the PR?), license, and that the source is what it claims. A plugin that promotes or wires a
third-party SaaS is a trust delegation — record accept/deny with rationale. Note the platform already blocks
plugin-shipped **agents** from declaring `hooks` / `mcpServers` / `permissionMode` "for security reasons" —
don't design around that.

Record accept/deny + rationale for any plugin touching surfaces 2, 5, or 6; a later version bump that
introduces a new surface re-triggers this review.

## Local development loop

For a plugin that already ships here, iterate against your local clone without re-publishing and
Expand Down
Loading