mirror of
https://github.com/anthropics/claude-plugins-official.git
synced 2026-07-04 02:33:30 +00:00
* policy(scan): review whole payload incl .claude/ + flag credential extraction The review rubric anchored "read every relevant file" to the loaded plugin surface (skills/*/SKILL.md, hook-referenced source) and checked credential reads (~/.ssh, ~/.aws/credentials) only within hooks. Code that reads the user's live secrets from a non-loaded location — e.g. a dotdir like .claude/ that still ships to the user's disk on a git-source install — could fall through both. Two fixes: - Scope: direct the reviewer to read the WHOLE shipped payload incl. dotdirs like .claude/ (clones to disk, agent-reachable though not auto-loaded). - Detector: add an explicit credential/secret-extraction check across ALL shipped code (not just hooks), naming OS credential-store CLIs + token harvest, with the set-your-own-key vs harvest trust-boundary distinction. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * policy(scan): scope credential-extraction flag to CROSS-service routing (cut same-service FPs) A full faithful scan of all 159 -official url-source plugins surfaced false positives: the credential clause flagged plugins that use the user's OWN service token to call that SAME service (e.g. a Railway plugin reading the Railway CLI token to call Railway; a gcloud token used against Google) — normal integration behavior. The "flag even if the destination is the vendor's own service" wording inverted the right rule. Corrected: flag only CROSS-service routing — a credential for service A sent to a DIFFERENT service or third party (the vercel-style misuse: Anthropic's ANTHROPIC_AUTH_TOKEN routed to a non-Anthropic endpoint). Same-service use (token for X used to call X) is explicitly NOT a violation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * policy(scan): judge credential ownership by NAME/source, not plugin-claimed use Refines the cross-service rule after the full -official re-validation showed the prior wording let a plugin pass by *claiming* an ANTHROPIC_*-named token was "its gateway key." Now: which service a credential belongs to is judged by its NAME / storage location (ANTHROPIC_AUTH_TOKEN => Anthropic; ~/.railway/config.json => Railway; ~/.aws/credentials => AWS), NOT by how the plugin repurposes it. So reading an ANTHROPIC_*-named token and routing it to a non-Anthropic endpoint is cross-service (flag) even if the code treats it as a gateway key; same-service use (Railway token -> Railway) still passes. Catches the wrong-credential-class trust-boundary breach while preserving the same-service FP fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci(validate): trigger on .github/policy/** so policy-prompt PRs clear the required check A PR touching only .github/policy/** matched none of the validate pull_request paths, so the required 'validate' check never ran via pull_request and sat Expected forever (a workflow_dispatch check run isn't associated with the PR, so it can't satisfy the gate). Mirrors the existing .github/workflows/** carve-out. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
54 lines
2.2 KiB
YAML
54 lines
2.2 KiB
YAML
name: Validate Plugins
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- '.claude-plugin/**'
|
|
- '*/.claude-plugin/**'
|
|
- '*/agents/**'
|
|
- '*/skills/**'
|
|
- '*/commands/**'
|
|
# `validate` is a required status check, so a PR that touches ONLY workflow
|
|
# files (e.g. an action-SHA re-pin) would otherwise never trigger validate
|
|
# and sit "Expected — Waiting for status to be reported" forever (workflow_dispatch
|
|
# check runs aren't associated with the PR, so they don't satisfy it). Run
|
|
# validate on workflow changes too so those PRs can clear the gate in-context.
|
|
- '.github/workflows/**'
|
|
# Same rationale for the scan policy prompt: a policy-only PR (.github/policy/**)
|
|
# touches none of the plugin paths above, so validate would never trigger via
|
|
# pull_request and the required check would sit "Expected" forever (a dispatch
|
|
# check run isn't associated with the PR, so it can't satisfy the gate either).
|
|
- '.github/policy/**'
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- '.claude-plugin/**'
|
|
# `validate` is a required status check on main. Bump PRs are opened with
|
|
# GITHUB_TOKEN, which doesn't fire on:pull_request (recursion guard), so the
|
|
# path-filtered trigger above never reports on them and the PR would be
|
|
# blocked forever. The bump workflow dispatches this against each per-entry
|
|
# bump branch instead; the check run lands on the branch HEAD (= PR head)
|
|
# and satisfies the required check. The validate job runs unconditionally,
|
|
# so a dispatch always reports.
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
validate:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- uses: anthropics/claude-plugins-community/.github/actions/validate-plugins@426e469f322952061102b286b378c0c9733a0934
|
|
with:
|
|
marketplace-path: .claude-plugin/marketplace.json
|
|
# Official curated marketplace: SHA-pin (I5) is a HARD error.
|
|
# I8/I11 are warnings until the 15 known vendored-path/name issues
|
|
# are cleaned up (see PR body); tighten to "I1 I3" after.
|
|
warn-invariants: "I1 I3 I8 I11"
|
|
claude-cli-version: latest
|