# How SkillSpector Detects MCP Least Privilege Violations: A Deep Dive into the LP1-LP4 Rules

> SkillSpector detects MCP least privilege violations by analyzing skill source code against declared permissions. Learn about the LP1-LP4 rules that identify under-declared, over-declared, wildcard, and missing permissions.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: deep-dive
- Published: 2026-06-21

---

**SkillSpector detects MCP least privilege violations by statically analyzing skill source code and comparing extracted capabilities against declared permissions in [`SKILL.md`](https://github.com/NVIDIA/SkillSpector/blob/main/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 parsed [`SKILL.md`](https://github.com/NVIDIA/SkillSpector/blob/main/SKILL.md) file containing the declared `permissions` list
- **`file_cache`** – A mapping of source file paths to their contents for static pattern scanning
- **`component_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`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/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:

1. **Executable Validation** – If no component metadata marks files as `executable` or the manifest is missing, the analyzer returns immediately without processing (lines 72-81).

2. **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 using `re.search(..., content, re.IGNORECASE)` (lines 40-90).

3. **Permission Mapping** – The `_map_permissions_to_categories()` function normalizes permission strings and matches them against capability categories using the `_PERM_TO_CAPABILITY` dictionary (lines 93-110).

4. **Finding Generation** – Depending on which LP rule triggers, the analyzer creates `Finding` objects 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:

```bash
skillspector analyze --analyzer mcp_least_privilege /path/to/skill

```

This command loads the skill's [`SKILL.md`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/SKILL.md) that triggers multiple violation types:

```yaml
name: dangerous-tool
description: Demonstrates MCP least privilege detection
permissions:
  - "*"
  - network
  - env

```

- The `"*"` wildcard triggers **LP2** (MEDIUM severity)
- If the code contains `subprocess.Popen` but lacks shell permissions, **LP1** fires (HIGH severity)
- Removing the `permissions` field while maintaining `requests` usage creates **LP3** (MEDIUM severity)
- Declaring `env` without environment access calls triggers **LP4** (LOW severity)

### Code That Triggers LP1 Violations

A minimal Python snippet that would be flagged for under-declared capabilities:

```python

# file: dangerous_tool.py

import subprocess

def run():
    subprocess.Popen(["/bin/ls", "-l"])

```

If [`SKILL.md`](https://github.com/NVIDIA/SkillSpector/blob/main/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_privilege` node in [`src/skillspector/nodes/analyzers/mcp_least_privilege.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/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_PATTERNS` before 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 `Finding` object 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`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/SKILL.md) with a `permissions` section is required to establish the baseline for comparison against detected code capabilities.