MCP Least Privilege Detection in SkillSpector: Complete Technical Guide

MCP Least Privilege detection in SkillSpector is a static analysis capability that audits Model Control Plane skills by comparing declared permissions in SKILL.md against actual runtime capabilities extracted from source code, flagging violations across four specific rule categories (LP1-LP4).

SkillSpector, NVIDIA's open-source skill auditing framework, implements MCP Least Privilege detection through a dedicated analyzer node that enforces the principle of least privilege. This security mechanism inspects executable files using regex pattern matching to ensure that skills cannot request broader permissions than their code actually requires, nor hide capabilities behind incomplete manifest declarations.

How the MCP Least Privilege Analyzer Works

The analyzer is implemented as the mcp_least_privilege node in src/skillspector/nodes/analyzers/mcp_least_privilege.py. During pipeline execution, it receives a SkillspectorState object containing three critical structures: the manifest (parsed SKILL.md with declared permissions), file_cache (source file contents for static analysis), and component_metadata (flags indicating executable files).

The LP1-LP4 Rule Set

According to the MCP least-privilege specification as implemented in NVIDIA/SkillSpector, the analyzer evaluates four distinct violation patterns:

Rule Violation Type Detection Mechanism Severity
LP1 Under-declared capabilities Code contains capabilities not covered by declared permissions HIGH
LP2 Wildcard permissions Manifest contains "*", "all", "full", or "any" MEDIUM
LP3 No permissions declared Capabilities detected but permissions field is missing or empty MEDIUM
LP4 Over-declared permissions Declared permissions have no matching code capability LOW

Detection Workflow

The node executes a four-phase analysis pipeline:

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

  2. Capability Extraction – For each executable file, _detect_capabilities() applies regex patterns from _CAPABILITY_PATTERNS using re.search(..., content, re.IGNORECASE) to identify shell, network, file I/O, environment, and MCP-specific API usage (lines 40-90).

  3. Permission Mapping – _map_permissions_to_categories() normalizes declared permission strings and matches them against _PERM_TO_CAPABILITY using word-boundary regexes (lines 93-110).

  4. Finding Generation – The analyzer compares declared categories against detected capabilities, creating Finding objects with descriptive messages, severity levels, and remediation advice (lines 96-152, 184-210, 222-280, 292-350).

Key Implementation Details

Wildcard Detection (LP2)

The _has_wildcard() function scans the permissions list for dangerous blanket values. When detected, the analyzer emits a MEDIUM severity finding to warn against overly permissive configurations.


# From src/skillspector/nodes/analyzers/mcp_least_privilege.py (lines 93-100)

if _has_wildcard(permissions):
    findings.append(Finding(
        message="Wildcard permission detected",
        severity="MEDIUM",
        # ... remediation advice

    ))

Under-Declared Capabilities (LP1)

This HIGH severity check identifies capabilities present in code that lack corresponding manifest entries. After gathering per-file capabilities into all_caps, the analyzer maps declared permissions to categories and reports any gap. Test-only capabilities receive reduced confidence scores (line 84).


# Capability comparison logic (lines 66-90)

declared_categories = _map_permissions_to_categories(permissions)
for cap in all_caps:
    if cap not in declared_categories:
        findings.append(Finding(
            severity="HIGH",
            message=f"Capability {cap} not declared in permissions"
        ))

Over-Declared Permissions (LP4)

Conversely, LP4 triggers when permissions exist in the manifest without supporting code evidence. Each permission maps to a capability category; if absent from all_caps, a LOW finding is emitted (lines 112-130).

Missing Permissions (LP3)

When _detect_capabilities() finds executable capabilities but the manifest lacks a permissions entry entirely, the analyzer raises a MEDIUM finding (lines 35-38). This catches cases where dangerous functionality exists without any security documentation.

Practical Examples

Running the Analyzer from CLI

Execute the MCP Least Privilege analyzer independently using the SkillSpector command-line interface:

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

This command loads the skill's SKILL.md, populates the file cache, and outputs a SARIF report containing LP1-LP4 findings.

Sample SKILL.md Violations

The following manifest configuration triggers multiple rule violations:

name: dangerous-tool
description: Demonstrates MCP least-privilege detection
permissions:
  - "*"
  - network
  - env
  • The "*" entry triggers LP2 (Wildcard permission)
  • Declaring env without environment access in code triggers LP4 (Over-declared)
  • Omitting shell permissions while using subprocess triggers LP1 (Under-declared)

Code That Triggers LP1

Consider this Python implementation where the skill executes shell commands:


# file: dangerous_tool.py

import subprocess

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

If SKILL.md only declares network permission, the analyzer reports an under-declared shell capability with HIGH severity, as the code performs shell execution without explicit permission.

Source File Reference

The MCP Least Privilege detection system spans these key files in the NVIDIA/SkillSpector repository:

Summary

  • MCP Least Privilege detection validates that skill permissions match actual code capabilities through static analysis.
  • The analyzer implements four violation rules (LP1-LP4) with severity rankings from HIGH (under-declared) to LOW (over-declared).
  • Detection relies on _CAPABILITY_PATTERNS regex matching against executable files and _PERM_TO_CAPABILITY mapping for manifest validation.
  • Findings are generated as structured Finding objects containing severity, confidence, and remediation guidance.
  • The analyzer can be invoked independently via skillspector analyze --analyzer mcp_least_privilege.

Frequently Asked Questions

What is the difference between LP1 and LP4 in MCP Least Privilege detection?

LP1 (Under-declared capabilities) occurs when code contains capabilities (such as shell execution or network access) that are not covered by any permission declared in SKILL.md, warranting a HIGH severity finding. LP4 (Over-declared permissions) occurs when the manifest lists permissions that have no corresponding capability detected in the source code, resulting in a LOW severity finding.

How does SkillSpector determine which files to analyze for capabilities?

The analyzer checks component_metadata to identify files marked as executable. Only executable components undergo capability extraction via _detect_capabilities(), while non-executable files are skipped to reduce false positives and improve performance.

What severity levels does the MCP Least Privilege analyzer assign to findings?

The analyzer uses a tiered severity system: HIGH for LP1 (under-declared capabilities that could enable unauthorized access), MEDIUM for LP2 (wildcard permissions) and LP3 (missing permissions declarations), and LOW for LP4 (over-declared permissions that represent principle-of-least-privilege violations but lower security risk).

Can the MCP Least Privilege analyzer run independently from other SkillSpector checks?

Yes. According to the CLI implementation in src/skillspector/cli.py, you can isolate the analyzer using the --analyzer flag: skillspector analyze --analyzer mcp_least_privilege /path/to/skill. This produces a focused SARIF report containing only LP1-LP4 findings without running other analysis nodes.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →