What Glob Rules Are Supported for Baseline Suppression in SkillSpector

SkillSpector supports standard Unix glob patterns—including *, ?, and character classes [a-z]—which are evaluated case-insensitively using Python's fnmatch module in src/skillspector/suppression.py.

NVIDIA's SkillSpector uses glob-based rules to filter security findings via baseline suppression files. These rules allow you to match against rule IDs, file paths, and message content using familiar wildcard syntax. Understanding the specific pattern features and matching behavior ensures your suppression baselines target precisely the findings you intend to exclude.

Supported Glob Pattern Syntax

SkillSpector's baseline suppression engine interprets glob patterns according to Python's fnmatch.fnmatch implementation. The following pattern metacharacters are supported:

Wildcards and Character Classes

  • * (asterisk): Matches any sequence of characters, including path separators. Use this to match files across directories or variable text within IDs.
  • ? (question mark): Matches any single character exactly once.
  • [abc] or [a-z]: Matches any single character within the specified set or range (character classes).

These patterns are processed in the _match_glob function (lines 72-83 of src/skillspector/suppression.py), which serves as the core matching engine for suppression rules.

Double Asterisk Handling

While Unix globbing often reserves ** for recursive directory matching, SkillSpector treats ** as a friendly alias for single *. The engine normalizes double asterisks to single asterisks on line 81 of suppression.py, meaning path: "**/SKILL.md" behaves identically to path: "*/SKILL.md".

Case Sensitivity Behavior

All glob matching in SkillSpector is case-insensitive. The _match_glob helper converts both the pattern and the value being matched to lowercase before evaluation (lines 73-82). This applies consistently to rule IDs and message globs, ensuring that id: "sqp-1" matches findings labeled "SQP-1" or "sqp-1" equally.

How Suppression Rules Match Findings

Suppression rules in SkillSpector contain three optional glob fields: id, path, and message. The matching logic in SuppressionRule.matches (lines 15-25) combines these fields to determine whether a finding should be suppressed.

Field-Specific Matching Logic

When evaluating a finding against a rule:

  • If a field (id, path, or message) is specified in the rule, the corresponding finding attribute must match the glob pattern.
  • If a field is omitted or set to null, it acts as a universal wildcard, matching any value for that attribute.
  • All specified fields must match simultaneously (AND logic) for the finding to be suppressed.

This design allows flexible scoping—from global suppression (specify only id) to highly targeted exclusions (combine id, path, and message patterns).

Match-All Protection

SkillSpector prevents accidental over-suppression by rejecting match-all rules. If a rule contains no id, path, or message fields, the matches method returns early (line 17) without suppressing any findings. This safety check ensures you cannot unintentionally silence all detections with an empty rule.

Practical Usage Examples

Define your suppression rules in a YAML or JSON baseline file:


# my-baseline.yaml

version: 1
rules:
  # Global suppression: matches this rule ID anywhere

  - id: "SQP-1"
    reason: "Trigger-phrase breadth is a description nit, not a vulnerability"

  # Scoped suppression: matches specific path and message patterns

  - id: "SSD-2"
    path: "*deploy-topology*/SKILL.md"
    message: "*run the exploit*"
    reason: "False positive - test-workflow phrase"

fingerprints:
  - hash: "sha256:1a2b3c4d5e6f7081"
    rule_id: "SDI-2"
    file: "baas-build-analysis/SKILL.md"
    reason: "Accepted 2026-06-19 - first-party env detection"

Load and apply the baseline programmatically:

from pathlib import Path
from skillspector.suppression import load_baseline, partition_findings

# Load baseline from YAML or JSON

baseline = load_baseline(Path("my-baseline.yaml"))

# Partition findings into kept and suppressed lists

kept, suppressed = partition_findings(findings, baseline)

print(f"Kept: {len(kept)}")
print(f"Suppressed: {len(suppressed)}")
for s in suppressed:
    print(f"- {s.finding.rule_id} in {s.finding.file}: {s.reason}")

The partition_findings function handles the evaluation logic, comparing each skillspector.models.Finding object against your glob rules and fingerprint hashes to categorize results.

Implementation Details in suppression.py

The core suppression logic resides in src/skillspector/suppression.py:

  • _match_glob (lines 72-83): Normalizes patterns (converting ** to *) and performs case-insensitive matching using fnmatch.fnmatch.
  • SuppressionRule.matches (lines 15-25): Orchestrates field-by-field glob comparison and implements the match-all protection guard.
  • load_baseline: Parses YAML/JSON suppression files into SuppressionRule objects.
  • partition_findings: Applies both glob-based and fingerprint-based suppression to categorize findings.

For complete pattern capabilities, refer to the docs/SUPPRESSION.md file in the repository, which documents the baseline format and glob syntax for end users.

Summary

  • SkillSpector uses Python fnmatch for glob evaluation in src/skillspector/suppression.py, supporting *, ?, and [abc] character classes.
  • ** is normalized to ***, functioning as a synonym for the single asterisk wildcard.
  • Matching is case-insensitive for both rule IDs and message content.
  • Omitting id, path, or message fields creates a wildcard for that attribute, but completely empty rules are rejected to prevent total suppression.
  • The SuppressionRule.matches method combines field-level glob matching with fingerprint-based exact matches for comprehensive baseline filtering.

Frequently Asked Questions

Does SkillSpector support recursive directory globs like **/?

No, SkillSpector does not implement recursive directory traversal semantics for **. In the _match_glob function (line 81), double asterisks are normalized to single asterisks, meaning **/ behaves exactly like */. This still matches across path separators, but does not provide distinct recursive directory matching behavior.

Are glob patterns case-sensitive in SkillSpector baselines?

No, glob matching is case-insensitive. The implementation converts both patterns and target values to lowercase before comparison (lines 73-82 in suppression.py). This applies to rule ID globs, path globs, and message content matching.

What happens if I omit fields like path or message in a suppression rule?

Omitted fields act as universal wildcards that match any value. For example, a rule specifying only id: "SQP-1" will suppress all findings with that rule ID regardless of file path or message content. However, SkillSpector rejects rules where all three fields (id, path, message) are absent to prevent accidental suppression of every finding.

Where is the glob matching logic implemented in the SkillSpector source code?

The glob matching logic is implemented in the _match_glob helper function within src/skillspector/suppression.py (lines 72-83). This function is invoked by SuppressionRule.matches (lines 15-25) to evaluate individual rule fields against finding attributes.

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 →