Skip to content

LP3 remediation advises adding a permissions field that Claude Code's SKILL.md schema does not have #313

Description

@RichCorbett

Summary

The LP3 code on main now accepts allowed-tools as a valid declaration:

permissions_absent = (permissions is None or permissions == []) and not allowed_tools

but the user-facing guidance was not updated alongside it. docs/B.3.1-mcp-least-privilege.md:163 still says:

Triggers when: The manifest has no permissions field (or it is an empty list) and the analyzer detects code capabilities in executable files.

and the remediation text points authors at permissions. grep -rn "allowed-tools" docs/ returns nothing.

Why it matters

For Claude Code skills, permissions is not a real field. The documented SKILL.md frontmatter schema uses allowed-tools / disallowed-tools for tool scoping. An author who follows the current remediation adds a permissions: key, Claude Code ignores it as unknown frontmatter, and LP3 keeps firing — the advice cannot resolve the finding.

The code change already concedes this; only the docs and the runtime remediation string are behind.

Supporting measurement

Across 817 skills from the public anthropic-cybersecurity-skills plugin, on main @ 34f6030:

  • LP3 fires on 791/817 (96.8%).
  • 0/817 declare permissions: and 0/817 declare allowed-tools: (parsed from the YAML frontmatter block only, not the file body — fenced YAML examples inside skill bodies produce false counts if you grep the whole file).
  • The firing rate is identical on 2.3.7 and 2.5.0, because with neither field present in the corpus the new allowed-tools clause never changes the outcome.

To be clear about scope: I am not reporting the 96.8% rate as a bug. LP3 behaves as designed and as documented, and "skills should declare their tool scope" is a defensible position. The issue is narrowly that the remediation names a field that does not exist in the target schema, so the finding is not actionable by its own advice.

For calibration, LP3 alone moves 39 skills across the >50 DO_NOT_INSTALL threshold in this corpus (256 → 217 with LP3 forced off), and the median from 30 to 23.

Suggested fix

Update docs/B.3.1-mcp-least-privilege.md and the runtime remediation string to name allowed-tools alongside permissions, and say which applies to which manifest type (MCP server manifest vs Claude Code SKILL.md). Small doc change; happy to PR it.

Environment

main @ 34f6030 (2.5.0) and 2.3.7 (ab0431f), Python 3.12, macOS.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions