* 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>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The ms365 / microsoft-365 entries ship M365 as a manual type:http MCP
server. That auth path cannot succeed: the M365 server's OAuth client
registration only permits the claude.ai callback, so any client-initiated
OAuth flow (localhost or claude:// redirect) is rejected by the identity
provider before the consent screen ever shows (AADSTS50011).
Users connect Microsoft 365 through the claude.ai Connectors directory
instead, which uses the registered callback and works. Plugin skills
reference tools via ~~category placeholders (see CONNECTORS.md), not the
ms365 server key, so no content changes are needed.
Bumps each touched plugin's version so the update distributes to
existing installs.
Co-authored-by: Claude <noreply@anthropic.com>