# How to Configure Baseline Glob Rules for Drift-Tolerant Suppression in SkillSpector

> Learn to configure baseline glob rules in NVIDIA SkillSpector for drift-tolerant suppression. This enables durable false-positive filtering across code edits without manual updates.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: how-to-guide
- Published: 2026-07-09

---

**SkillSpector enables durable false-positive filtering through YAML-based glob rules that match findings by pattern rather than exact line hashes, allowing suppressions to persist across code edits without manual baseline updates.**

SkillSpector, NVIDIA's open-source skill security analyzer, provides a sophisticated suppression system that survives code refactoring. Configuring **baseline glob rules for drift-tolerant suppression** allows security teams to silence recurring false positives using pattern matching instead of brittle line-specific fingerprints, significantly reducing maintenance overhead as skills evolve.

## Understanding the Baseline File Structure

A baseline file contains two distinct suppression mechanisms. The `rules` section houses **drift-tolerant** glob-based suppressions, while the `fingerprints` section stores exact hash-based suppressions that bind to specific line content. Unlike fingerprints, glob rules remain effective when line numbers shift or message text changes slightly during development.

### Rule Matching Fields

Each rule in the `rules` array is a YAML object supporting these optional fields:

- **id** or **rule_id**: Glob pattern matching `Finding.rule_id` (supports `*` and `?` wildcards)
- **path** or **file**: Glob pattern matching the file path; `**` normalizes to `*` for cross-platform compatibility
- **message**: Case-insensitive glob matching `Finding.message`; wrap keywords in `*` for substring matching
- **reason**: Human-readable justification stored in audit trails and reports

A rule matches a finding only when **every specified field** matches the corresponding finding attribute. Unspecified fields act as wildcards, so a rule defining only `id` suppresses that rule ID globally across the entire codebase.

## Implementation in the Suppression Engine

The suppression logic resides in [src/skillspector/suppression.py](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/suppression.py).

The `SuppressionRule` dataclass implements the `matches()` method, which validates each populated field using case-insensitive `fnmatch` comparisons (lines 10-25). The helper `_match_glob()` normalizes `**` to `*` and performs platform-agnostic pattern matching (lines 72-83).

When evaluating findings against the baseline, `Baseline.reason_for()` iterates through all loaded rules and returns the first matching rule's `reason` string (lines 50-58). If no glob rule matches, the system falls back to fingerprint comparison for exact suppression.

During the analysis pipeline, [src/skillspector/nodes/report.py](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py) loads the baseline and invokes `partition_findings()` (lines 26-46) to segregate findings into kept and suppressed lists before SARIF generation and risk score calculation.

## Configuring and Using Baseline Rules

### Creating a Drift-Tolerant Baseline

Create a [`.skillspector-baseline.yaml`](https://github.com/NVIDIA/SkillSpector/blob/main/.skillspector-baseline.yaml) file with glob rules that survive code edits:

```yaml
version: 1
rules:
  - id: "SQP-1"
    reason: "Trigger-phrase breadth is a description nit, not a vulnerability"
  - id: "SSD-2"
    path: "*deploy-topology*/SKILL.md"
    message: "*run the exploit*"
    reason: "False positive: benign lab-test phrase"
fingerprints: []

```

### CLI Commands

Generate baselines and apply drift-tolerant suppression via the command line:

```bash

# Create baseline with current findings stored as fingerprints

skillspector baseline ./my-skill/ -o .skillspector-baseline.yaml

# Scan applying drift-tolerant glob rules

skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml

# Include suppressed findings in output for security auditing

skillspector scan ./my-skill/ --baseline .skillspector-baseline.yaml --show-suppressed

```

### Python API Integration

Apply suppression rules programmatically in custom workflows:

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

baseline = load_baseline(Path(".skillspector-baseline.yaml"))
kept, suppressed = partition_findings(findings_list, baseline)

for item in suppressed:
    print(f"Suppressed {item.finding.rule_id}: {item.reason}")

```

## Summary

- **Baseline glob rules** provide pattern-based suppression that survives code edits and line number shifts.
- Rules match on `id`, `path`, and `message` using case-insensitive glob patterns implemented via `fnmatch`.
- The `SuppressionRule` class in [suppression.py](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/suppression.py) handles drift-tolerant matching, while `partition_findings()` splits findings into kept and suppressed sets.
- Use `--baseline` in the CLI to apply rules; suppressed findings are excluded from risk scores and SARIF output unless using `--show-suppressed`.

## Frequently Asked Questions

### What makes glob rules "drift-tolerant" compared to fingerprints?

Fingerprint suppression relies on exact content hashes that invalidate when lines shift or text changes. Glob rules match patterns such as `*run the exploit*` in the message field or `**/test-*/SKILL.md` in the path field, remaining valid even when line numbers move or surrounding text evolves, because they match structural patterns rather than byte-level identity.

### Can I combine glob rules and fingerprints in the same baseline?

Yes. The baseline file supports concurrent `rules` and `fingerprints` sections. SkillSpector checks glob rules first via `Baseline.reason_for()`, then falls back to fingerprint matching. This allows drift-tolerant patterns for recurring false positives while reserving exact fingerprints for specific one-off suppressions that should not match similar findings elsewhere.

### How does case-insensitive matching work in message globs?

The `_match_glob()` helper in [suppression.py](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/suppression.py) normalizes both the pattern and finding message text to lowercase before applying `fnmatch`, ensuring that `*Exploit*` matches "exploit", "EXPLOIT", or "Exploit" without requiring multiple rule variations or complex regex syntax.

### Where are suppressed findings filtered in the analysis pipeline?

The report node in [src/skillspector/nodes/report.py](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py) loads the baseline during scan initialization and calls `partition_findings()` from [suppression.py](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/suppression.py) to bifurcate findings into kept and suppressed lists. This filtering occurs after rule evaluation but before SARIF serialization and risk score aggregation, ensuring suppressed items do not influence the final security assessment.