DriftBuster inspects configuration trees, recognises familiar formats, and describes the differences so you can rein in infrastructure drift before it becomes an outage.
Note: The primary experience is a .NET 8 Windows GUI backed by a shared backend. The Python engine provides the detection core, offline runner, and developer tooling used by the GUI and PowerShell module.
- Precise format detection – pluggable analyzers use bounded sampling to process large trees without overwhelming the collector.
- Explainable results – each hit includes format, variant, and the reason the detector fired so you can audit decisions instead of trusting a black box.
- Profiles and hunt mode – codify expectations, ignore volatile values, and alert when a snapshot slips outside your guardrails.
- First-class diff reporting – the
driftbuster.reporting
helpers produce JSON/text/HTML ready for hand-off or automation, with optional redaction. - Cross-platform UI – the Avalonia desktop front-end ships alongside the Python engine for quick triage and demo flows.
- Windows Registry live scans – enumerate apps, suggest likely registry
roots, and search values by keyword/regex (see
docs/registry.md
).
- Python 3.12 or newer
dotnet
8.0 SDK (only for the GUI or .NET build pipeline)
Clone the repository and install the Python package in editable mode:
git clone https://github.com/techjoec/DriftBuster.git
cd DriftBuster
python -m pip install -e .
Install optional tooling used by the compliance workflow:
python -m pip install detect-secrets pip-licenses
python -m driftbuster.cli fixtures/config --glob "*.config"
- Add
--json
to capture machine-readable results. - Use
--max-sample
to override the default 128 KiB sampling window. - Pass
--profile <path>
to apply a configuration profile while scanning.
python -m driftbuster.cli export-sql fixtures/sqlite/sample.sqlite \
--mask-column accounts.secret \
--hash-column accounts.email \
--placeholder "[MASK]" \
--hash-salt pepper
- Multiple database paths are supported; each export is listed in
sql-manifest.json
with table counts and masking metadata. - Use
--output-dir
to control the destination directory (defaults tosql-exports/
).
from driftbuster import scan_path, registry_summary
summary = registry_summary()
results = scan_path("fixtures/config")
results
yields ProfiledDetection
objects ready for further filtering,
diffing, or reporting.
dotnet run --project gui/DriftBuster.Gui/DriftBuster.Gui.csproj
The GUI uses the shared .NET backend library to show hunts, diffs, and profile mismatches interactively.
Tips:
- Use the header theme toggle to switch Dark/Light.
- Click “Check core” to verify backend health (status dot shows green/red).
- Primary actions are accent-filled; secondary are outline for quick scanning.
- Start the GUI from the repo root:
dotnet run --project gui/DriftBuster.Gui/DriftBuster.Gui.csproj
. - Switch to the Multi-server tab, enable the host slots you need, and add roots or pick scope chips. Drag host cards to reorder execution priority and turn on the session cache toggle if you want to reuse labels, filters, and layout next time (the snapshot is stored under your DriftBuster data root, e.g.
%LOCALAPPDATA%/DriftBuster/sessions/multi-server.json
). - Click Run all to queue every active host. Use Run missing only for retries; toasts and the activity timeline record progress, warnings, and exports.
- Review the catalog filters, open drilldown diffs (including the inline View drilldown shortcut from the host summary), and export HTML/JSON snapshots (they land in
artifacts/exports/<config>-<timestamp>.{html,json}
).
Run the same plan from the shell:
python -m driftbuster.multi_server <<'JSON'
{
"plans": [
{
"host_id": "server01",
"label": "Baseline",
"roots": ["samples/multi-server/server01"]
},
{
"host_id": "server02",
"label": "Drift sample",
"roots": ["samples/multi-server/server02"]
}
]
}
JSON
driftbuster.multi_server
ships with the Python package; ensure you have installed the repo in editable mode (python -m pip install -e .
). The CLI and GUI share an OS-specific data root (e.g. %LOCALAPPDATA%/DriftBuster
, $XDG_DATA_HOME/DriftBuster
); set DRIFTBUSTER_DATA_ROOT
to override where cached diffs live. See docs/multi-server-demo.md
for annotated callouts, filter usage, and rerun tips.
The lightweight CLI stub remains paused. Packaging prerequisites and manual
validation drills live in notes/status/cli-plan.md
; use that plan when the
CLI workstream resumes. Until then you can rehearse the entry points locally by
installing the project in editable mode and invoking the console scripts:
python -m pip install -e .
driftbuster samples/config
driftbuster-export-sql fixtures/sqlite/sample.sqlite --output-dir exports
Current argument surface (captured in artifacts/cli-plan/README.md
alongside
expected outputs):
Command | Arguments | Purpose |
---|---|---|
driftbuster |
PATH |
Scan a file or directory using detector defaults. |
--glob PATTERN |
Restrict directory recursion (default **/* ). |
|
--sample-size BYTES |
Override detector sampling window. | |
--json |
Emit JSON lines instead of a table. | |
--min-confidence VALUE (planned) |
Filter matches below the configured confidence floor. | |
driftbuster export-sql |
DATABASE [DATABASE…] |
Export anonymised SQLite snapshots. |
--output-dir PATH |
Destination for snapshots and manifest. | |
--table NAME / --exclude-table NAME |
Include/exclude specific tables. | |
--mask-column TABLE.COLUMN |
Replace sensitive values with placeholders. | |
--hash-column TABLE.COLUMN |
Deterministically hash column values. | |
--placeholder TEXT |
Placeholder text when masking columns. | |
--hash-salt TEXT |
Salt applied to hashed values. | |
--limit COUNT |
Cap exported rows per table. | |
--prefix TEXT |
Prefix generated snapshot filenames. | |
--manifest-name NAME |
Override manifest filename. | |
--no-progress (planned) |
Suppress progress indicators once implemented. |
- Python + .NET installer (default):
python scripts/release_build.py --release-notes notes/releases/<semver>.md --installer-rid win-x64
- Installer artifacts:
artifacts/velopack/releases/<rid>
- Portable GUI publish only:
python scripts/release_build.py --no-installer
dotnet build gui/DriftBuster.Backend/DriftBuster.Backend.csproj
pwsh scripts/lint_powershell.ps1
Import-Module ./cli/DriftBuster.PowerShell/DriftBuster.psd1
Invoke-DriftBusterDiff -Versions 'fixtures/config/appsettings.json','fixtures/config/web.config'
Export-DriftBusterSqlSnapshot -Database fixtures/sqlite/sample.sqlite -MaskColumn accounts.secret -HashColumn accounts.email
The PowerShell module uses the shared DriftBuster.Backend
library, giving the
CLI and GUI identical diff, hunt, and run-profile behaviour.
To publish a redistributable archive, run:
dotnet build gui/DriftBuster.Backend/DriftBuster.Backend.csproj -c Release
pwsh ./scripts/package_powershell_module.ps1 -Configuration Release -SkipAnalyzer
Get-Content artifacts/powershell/releases/DriftBuster.PowerShell-<version>.zip.sha256
The script emits DriftBuster.PowerShell-<version>.zip
and an accompanying .sha256
file under artifacts/powershell/releases/
; verify the checksum before distributing the module.
If importing the module reports DriftBusterBackendMissing
, publish the backend
assembly and re-import:
dotnet publish gui/DriftBuster.Backend/DriftBuster.Backend.csproj -c Debug -o gui/DriftBuster.Backend/bin/Debug/published
Import-Module ./cli/DriftBuster.PowerShell/DriftBuster.psd1 -Force
Copying the resulting DriftBuster.Backend.dll
next to DriftBuster.psm1
also
unblocks import when working from a published module archive.
- Catalog (
src/driftbuster/catalog.py
) – central listing of detection capabilities, metadata, and sampling rules. - Plugins (
src/driftbuster/formats/
) – individual format detectors. Register new plugins withdriftbuster.formats.register
. - Profiles (
docs/configuration-profiles.md
) – YAML definitions of expected values; usedriftbuster.profile_cli
to generate, diff, and apply them. - Hunt rules (
src/driftbuster/hunt.py
) – skim snapshots for high-priority strings such as secrets or machine identifiers.
Check docs/
for deeper dives:
docs/profile-usage.md
– practical walkthrough of profiles and hunts.docs/format-support.md
– current detector coverage.docs/customization.md
– configuration flags, sampling tweaks, and plugin lifecycles.docs/testing-strategy.md
– how we validate detectors and reporting.docs/multi-server-demo.md
– multi-server orchestration walkthrough covering GUI callouts, CLI parity, and troubleshooting.docs/day0-baseline.md
– create a Day 0 baseline across many servers without an existing reference.docs/DEMO.md
– GUI walkthrough using the bundled demo data.docs/versioning.md
– component version workflow and sync tooling.docs/registry.md
– Windows Registry live scan overview and API usage.
dotnet test gui/DriftBuster.Gui.Tests/DriftBuster.Gui.Tests.csproj --configuration Release --no-build
python -m pytest
Optional local checks:
- Secret scanning:
detect-secrets scan
- License audit:
pip-licenses
- Maintain ≥ 90% line coverage for Python sources under
src/
and for the .NET surface (GUI + backend). Enforce locally with:- Python:
coverage run --source=src/driftbuster -m pytest -q && coverage report --fail-under=90
- .NET:
dotnet test -p:Threshold=90 -p:ThresholdType=line -p:ThresholdStat=total gui/DriftBuster.Gui.Tests/DriftBuster.Gui.Tests.csproj
- Python:
- Quick all-in-one:
./scripts/verify_coverage.sh
- Runs Python tests with
coverage report --fail-under=90
- Runs .NET tests with
-p:Threshold=90 -p:ThresholdType=line -p:ThresholdStat=total
- Prints a combined summary via
python -m scripts.coverage_report
- Runs Python tests with
Two coverage surfaces exist: Python (engine, detectors, reporting) and .NET (GUI + backend).
- Python
- Quick:
coverage run --source=src/driftbuster -m pytest -q && coverage report -m
- JSON:
coverage json -o coverage.json
- HTML (optional):
coverage html
→ openhtmlcov/index.html
- Quick:
- .NET GUI
- Cobertura XML:
dotnet test gui/DriftBuster.Gui.Tests/DriftBuster.Gui.Tests.csproj --collect:"XPlat Code Coverage" --results-directory artifacts/coverage-dotnet
- The XML lands under
artifacts/coverage-dotnet/<run-id>/coverage.cobertura.xml
.
- Cobertura XML:
Repo‑wide summary:
python -m scripts.coverage_report
- Follow the checklist in
docs/plugin-test-checklist.md
. - Add plugin tests under
tests/formats/
and keep the plugin module’s per-file coverage ≥ 90%.
This prints Python percent, .NET Cobertura percent, and the most under‑covered GUI classes to guide test additions.
src/driftbuster/
├─ core/ # Detector orchestration, profiles, and diffing
├─ formats/ # Built-in format plugins
├─ reporting/ # Emit JSON/text/HTML reports
└─ … # CLI entrypoints and hunt utilities
gui/ # Avalonia desktop app (C# / .NET 8)
tests/ # Python unit tests covering detectors and CLI
docs/ # Developer guides, roadmaps, and playbooks
scripts/ # Release helpers and capture tooling
- Fork and branch from
main
. - Run the Python and .NET test suites before opening a pull request.
- Document provenance in the PR template and update relevant guides.
See CONTRIBUTING.md
, docs/legal-safeguards.md
, and
docs/reviewer-checklist.md
for detailed expectations.
DriftBuster is licensed under the Apache License 2.0 (LICENSE
). Related legal
documents live in NOTICE
, CLA/INDIVIDUAL.md
, and CLA/ENTITY.md
.