How SkillSpector Detects MCP Least Privilege Violations: A Deep Dive into the LP1-LP4 Rules
SkillSpector detects MCP least privilege violations by statically analyzing skill source code and comparing extracted capabilities against declared permissions in SKILL.md, using a four-rule framework (LP1-LP4) that flags under-declared, over-declared, wildcard, and missing permissions with appropriate severity levels.
SkillSpector is NVIDIA's security analysis framework designed to audit Model Control Plane (MCP) skills for security best practices. The detection of MCP least privilege violations centers on the mcp_least_privilege analyzer node, which implements a comprehensive static analysis pipeline that correlates code capabilities with manifest declarations to ensure skills operate with minimal necessary permissions.
How the MCP Least Privilege Analyzer Works
The analyzer operates as a node within the SkillSpector pipeline, receiving a SkillspectorState object containing three critical data sources:
manifest– The parsedSKILL.mdfile containing the declaredpermissionslistfile_cache– A mapping of source file paths to their contents for static pattern scanningcomponent_metadata– Metadata indicating which files are executable and should be analyzed
When invoked, the node executes a multi-phase detection workflow that implements the MCP least-privilege specification's LP1-LP4 rule set.
The LP1-LP4 Rule Framework
The analyzer categorizes violations into four distinct rule types, each with specific detection logic and severity assignments defined in src/skillspector/nodes/analyzers/mcp_least_privilege.py.
LP2: Wildcard Permission Detection
LP2 identifies overly permissive declarations where the permissions list contains wildcard values such as "*", "all", "full", or "any". The _has_wildcard() function scans the permissions array using case-insensitive matching, and when detected, emits a MEDIUM severity finding (lines 93-100). This rule prevents skills from requesting blanket access when specific capabilities would suffice.
LP3: Missing Permissions Declaration
LP3 triggers when executable code contains capabilities but the SKILL.md manifest lacks a permissions entry entirely or declares an empty list. The analyzer first extracts capabilities from every executable file via _detect_capabilities(), which applies regex patterns from _CAPABILITY_PATTERNS to file contents. If permissions is missing or empty while all_caps contains any detected capabilities, the node emits a MEDIUM finding (lines 35-38).
LP1: Under-Declared Capabilities
LP1 represents the most critical violation: code capabilities that exist in the source but are not covered by any declared permission. After gathering per-file capabilities, _map_permissions_to_categories() converts each declared permission string into a capability category using word-boundary regexes against the _PERM_TO_CAPABILITY mapping. Any capability present in the code but absent from the derived declared_categories set generates a HIGH severity finding (lines 66-90). Test-only capabilities receive a lower confidence score to reduce false positives (line 84).
LP4: Over-Declared Permissions
LP4 identifies permission bloat by detecting declared permissions that have no corresponding code capability. For each permission in the manifest, the analyzer maps it to its capability category; if that category is absent from the detected all_caps set, a LOW severity finding is emitted (lines 112-130). This encourages developers to remove unused permissions that expand the attack surface.
Detection Workflow in Detail
The analyzer follows a strict execution path when processing a skill:
-
Executable Validation – If no component metadata marks files as
executableor the manifest is missing, the analyzer returns immediately without processing (lines 72-81). -
Capability Extraction – For each executable file,
_detect_capabilities()applies static regex patterns covering shell execution, network operations, file I/O, environment access, and MCP-specific APIs usingre.search(..., content, re.IGNORECASE)(lines 40-90). -
Permission Mapping – The
_map_permissions_to_categories()function normalizes permission strings and matches them against capability categories using the_PERM_TO_CAPABILITYdictionary (lines 93-110). -
Finding Generation – Depending on which LP rule triggers, the analyzer creates
Findingobjects containing descriptive messages, severity levels, confidence scores, and remediation advice (lines 96-152, 184-210, 222-280, 292-350).
The node concludes by logging the total finding count and returning {"findings": findings} to the analysis framework.
Practical Examples
Running the Analyzer from CLI
Invoke the MCP least privilege analyzer directly from the command line:
skillspector analyze --analyzer mcp_least_privilege /path/to/skill
This command loads the skill's SKILL.md, caches source files into the file_cache, and executes the node function described above, outputting a SARIF report containing LP1-LP4 findings.
SKILL.md Configuration Examples
Consider a SKILL.md that triggers multiple violation types:
name: dangerous-tool
description: Demonstrates MCP least privilege detection
permissions:
- "*"
- network
- env
- The
"*"wildcard triggers LP2 (MEDIUM severity) - If the code contains
subprocess.Popenbut lacks shell permissions, LP1 fires (HIGH severity) - Removing the
permissionsfield while maintainingrequestsusage creates LP3 (MEDIUM severity) - Declaring
envwithout environment access calls triggers LP4 (LOW severity)
Code That Triggers LP1 Violations
A minimal Python snippet that would be flagged for under-declared capabilities:
# file: dangerous_tool.py
import subprocess
def run():
subprocess.Popen(["/bin/ls", "-l"])
If SKILL.md only declares network permission, the analyzer detects the shell execution capability and reports an LP1 violation because the subprocess usage exceeds the declared permissions.
Summary
- SkillSpector implements MCP least privilege detection through the
mcp_least_privilegenode insrc/skillspector/nodes/analyzers/mcp_least_privilege.py - Four distinct rules (LP1-LP4) cover under-declared capabilities, wildcard permissions, missing declarations, and over-declared permissions
- Static regex analysis extracts capabilities from executable files using
_CAPABILITY_PATTERNSbefore comparing against manifest declarations - Severity levels range from HIGH (LP1) for dangerous under-declarations to LOW (LP4) for unused permissions
- Remediation guidance is embedded in each
Findingobject to help developers align permissions with actual code requirements
Frequently Asked Questions
What is the difference between LP1 and LP4 violations?
LP1 (Under-Declared Capabilities) occurs when code performs actions not covered by declared permissions, representing a security risk where the skill may lack necessary restrictions. LP4 (Over-Declared Permissions) occurs when permissions are declared but never used by the code, representing permission bloat that violates least privilege principles. LP1 carries HIGH severity while LP4 carries LOW severity.
How does SkillSpector identify capabilities in source code?
The analyzer uses the _detect_capabilities() function in src/skillspector/nodes/analyzers/mcp_least_privilege.py to apply regex patterns defined in _CAPABILITY_PATTERNS against file contents. These patterns identify shell execution, network requests, file system operations, environment variable access, and MCP API calls through case-insensitive regular expression matching.
What severity levels does the MCP least privilege analyzer assign?
The analyzer assigns HIGH severity to LP1 under-declared capabilities, MEDIUM severity to LP2 wildcard permissions and LP3 missing declarations, and LOW severity to LP4 over-declared permissions. Each finding includes a confidence score, with test-only capabilities receiving reduced confidence to minimize false positives.
Can SkillSpector analyze skills without a SKILL.md manifest?
The analyzer checks for manifest presence at the beginning of the detection workflow (lines 72-81). If no SKILL.md exists or no files are marked as executable in the component_metadata, the node returns immediately without generating findings. For complete least privilege analysis, a SKILL.md with a permissions section is required to establish the baseline for comparison against detected code capabilities.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →