Skip to content

Plugin bin/ deploy: trust-posture, producer docs, and hardening follow-ups (from #1591 review panel) #1620

@danielmeppiel

Description

@danielmeppiel

Tracks the deferred, improvement-tier follow-ups surfaced by the advisory review panel on #1591 (marketplace_plugin bin/ deployment to ~/.claude/skills/<name>/). None blocked #1591; the highest-signal findings were folded there (manifest symlink guard, governance.md Rule-4 drift, native-skill+bin/ and symlink-rejection regression tests, doc wording). This issue collects the rest.

1. Trust posture: opt-in / first-deploy consent (security + DevX)

Both supply-chain-security and devx-ux flagged that default-on bin/ deployment places package executables on Claude Code's PATH without explicit consent. v1 ships with the bin_deploy deny / deny_all policy escape hatch and matches npm's bin-link mental model, so this is a v2 design call, not a regression.

  • Consider an opt-in flag (--deploy-bin) or a prominent first-deploy warning on the first install of any new plugin that ships bin/.
  • Surfaces: src/apm_cli/integration/skill_integrator.py (_deploy_plugin_bin).

2. Producer-facing "publishing plugins with binaries" guide (growth + docs)

The feature is currently documented only on the admin opt-out surface (policy-schema.md + apm-usage/governance.md). A plugin author has no entry point describing the 3-step path (add bin/, ensure marketplace_plugin package type, publish).

  • Add a short producer/authoring guide page and cross-link it from the bin_deploy policy section.
  • Story angle for the next minor: "Ship your CLI as an APM plugin -- Claude invokes it like a native command."

3. Least-privilege hardening (security)

  • Tighten the deployed-executable mode from group+other execute toward user-only execute (0o700-style), given the ~/.claude/skills/ user-scope constraint. Land before any future system-scope expansion.
  • Normalize bin_deploy.deny matching (case / host-prefix) or document that entries must be lowercase canonical owner/name.
  • Surfaces: _copy_plugin_file (~chmod), _bin_deploy_denied (deny match).

4. Project-scope silent no-op hint (DevX)

A marketplace_plugin that ships bin/ installed at project scope silently does not deploy executables. Emit a visible hint to re-run with -g.

  • Surface: src/apm_cli/integration/skill_integrator.py (project-scope skip path).

5. _merge_bin_paths value-object hygiene (architecture)

_merge_bin_paths mutates a non-frozen SkillIntegrationResult in place yet also returns it (modify-then-return). Prefer dataclasses.replace() for a pure value-object pattern, matching policy/schema.py. Prevents future bugs if the result is ever frozen or shared across threads.

6. (Deferred architecture) TargetProfile plugin-bin contract

The Claude-specific gate (target.name == "claude") is honest single-consumer v1 code. If/when a second harness ships the same skills-directory-plugin contract, extract a TargetPluginBinContract protocol and move the harness-specific logic behind it.


Source: advisory review panel on #1591 (python-architect, cli-logging-expert, devx-ux-expert, supply-chain-security-expert, oss-growth-hacker, doc-writer, test-coverage-expert; apm-ceo synthesis stance ship_with_followups).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/cliCLI command surface, flags, help text (cross-cutting).area/docs-sitedocs/src/content (Starlight), README, doc generation.area/marketplacemarketplace.json schema, federation, authoring suite, source parity.enhancementDeprecated: use type/feature. Kept for issue history; will be removed in milestone 0.10.0.priority/lowAccepted but not time-sensitivestatus/acceptedDirection approved, safe to start work.status/triagedInitial agentic triage complete; pending maintainer ratification (silence = approval).theme/securitySecure by default. Content scanning, lockfile integrity, MCP trust boundaries.type/featureNew capability, new flag, new primitive.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions