Skip to main content

repo-sentinel-lite

Deterministic Python CLI for repository hygiene checks, lightweight secret-adjacent scanning, and baseline-backed pre-commit validation.

repo-sentinel-lite scans a repository and emits stable JSON for:

  • suspicious filenames such as .env, *.pem, id_rsa, and *.kdbx
  • high-entropy strings that look like secrets
  • structured secret-adjacent patterns such as PEM private-key headers, GitHub-token-like prefixes, AWS access-key-like prefixes, and generic token= or api_key= assignment contexts
  • missing standard files such as README.md, LICENSE, and .gitignore

It also supports .reposentinel.toml overrides, scoped allowlists, JSON baselines for suppressing known findings, baseline drift audits, changed-file scans, and a pre-commit provider for repository-local enforcement. Token-like values are redacted in CLI output and generated baselines by default.

The detector set is intentionally heuristic. A clean scan is useful repository hygiene evidence, not proof that no credential exists in the repository or its history.

Install

Install from production PyPI:

python -m pip install repo-sentinel-lite

Requires Python 3.11 or newer.

Usage

More copy-pasteable CLI workflows are in docs/cli-recipes.md. For the shortest consumer setup path, see docs/consumer-minimal-setup.md. For baseline review expectations and a sample baseline, see docs/baseline-review.md. For output stability and CI artifact guidance, see docs/output-format-stability.md. For pre-commit provider setup, see docs/pre-commit-integration.md. For threat model boundaries and non-goals, see docs/threat-model.md. For the v0.8 synthetic performance envelope, see docs/performance-envelope-v0.8.md. For self-dogfooding status, see docs/self-dogfooding.md. For the short external case study, see How repo-sentinel-lite Dogfoods Repository Hygiene. For near-term review boundaries, see ROADMAP.md. For before-and-after scanner examples, see examples/. The v0.7 adoption plan is tracked in docs/v0.7-adoption-release.md. Release notes for v0.7.1 are tracked in docs/release-notes-v0.7.1.md. Release notes for v0.8.0 are tracked in docs/release-notes-v0.8.0.md. Release notes for the v0.8.1 registry recovery are tracked in docs/release-notes-v0.8.1.md.

Scan the current repository. This defaults to deterministic JSON output:

repo-sentinel scan

Emit deterministic JSON explicitly for a specific path:

repo-sentinel scan --format json path/to/repo

Render a concise text summary for a specific path:

repo-sentinel scan --format text path/to/repo

Scan a specific path and save a baseline:

repo-sentinel scan --write-baseline baseline.json path/to/repo

Scan with an existing baseline applied:

repo-sentinel scan --baseline baseline.json path/to/repo

Audit baseline drift without suppressing the classification output:

repo-sentinel baseline audit --baseline baseline.json path/to/repo

If the scanned repository already contains .reposentinel-baseline.json, repo-sentinel scan applies it automatically.

Temporarily scan without the repository-root default baseline:

repo-sentinel scan --no-default-baseline path/to/repo

Fail with exit code 1 when unsuppressed findings remain:

repo-sentinel scan --fail-on-findings path/to/repo

Reveal full high-entropy tokens only when you explicitly need to inspect them:

repo-sentinel scan --reveal-secrets path/to/repo

Python API

The package-level API returns a deep-redacted report by default:

from pathlib import Path

from repo_sentinel import scan_repository

report = scan_repository(Path("path/to/repo"))

Pass reveal_secrets=True only for an intentional local investigation:

sensitive_report = scan_repository(
    Path("path/to/repo"),
    reveal_secrets=True,
)

The revealed result can contain credential-like token bodies. Do not log, upload, or persist it as an ordinary report. Existing low-level integrations that import repo_sentinel.scanner.scan_repository receive the sensitive internal report for compatibility; new integrations should use the package-level API above.

Use a .reposentinel.toml config to ignore paths or adjust thresholds:

ignore_globs = ["dist/**", ".venv/**"]
entropy_threshold = 4.2
max_text_file_size = 1048576

[allowlist]
paths = ["fixtures/**"]
rules = ["repo.suspicious_filename"]
token_hashes = ["sha256:3eb1bd439947"]

Use rule_id values from JSON findings when writing rule-scoped allowlists.

Configuration loading fails closed. Only an absent .reposentinel.toml uses defaults; unreadable files, invalid TOML or values, and unknown top-level or [allowlist] keys return CLI exit code 2. Diagnostics name the repository- relative config file without printing the scanned root's absolute path.

The legacy aliases suspicious_patterns, allowlist_paths, allowlist_rules, and allowlist_token_hashes remain accepted for compatibility. New configs should use suspicious_filenames and the nested [allowlist] keys shown above.

Child-glob ignores such as fixtures/*, fixtures/**, and fixtures/**/* prune the matching directory during traversal.

Common generated and dependency directories such as .venv, venv, .venv-*, node_modules, dist, dist-*, build, .tox, .nox, .pytest_cache, .ruff_cache, .mypy_cache, *.egg-info, coverage, htmlcov, and __pycache__ are ignored by default. Text files larger than max_text_file_size bytes are skipped for high-entropy content scanning by default. The default symlink policy never follows file or directory symlinks. Link names still participate in hygiene checks, while target names and contents do not. Directory links and loops are pruned before descent; changed-file paths that cross a directory link are skipped.

When content inspection is skipped, JSON adds a deterministic coverage object with repository-relative paths, totals, and one of binary, oversize, symlink_policy, unreadable, or unsupported_encoding for each skipped file. Text output appends the same list, and SARIF stores it in the run-level properties.repoSentinelCoverage property. Coverage diagnostics are informational: they do not change exit status or become suppressible findings. The field is omitted when no discovered file is skipped, preserving existing clean-scan output. When directory symlinks are skipped, coverage also adds directories_skipped and skipped_directories without changing the file counters.

For pre-commit or local review paths that already know the changed files, scan only those files while keeping repository-level required-file checks:

repo-sentinel scan --changed-files path/to/repo src/app.py docs/example.md

Local development

Use Python 3.11 or newer, then run:

python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m pytest -q
ruff check .

These commands match the GitHub Actions CI workflow: .github/workflows/ci.yml

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

repo_sentinel_lite-0.8.1.tar.gz (49.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

repo_sentinel_lite-0.8.1-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

Details for the file repo_sentinel_lite-0.8.1.tar.gz.

File metadata

  • Download URL: repo_sentinel_lite-0.8.1.tar.gz
  • Upload date:
  • Size: 49.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for repo_sentinel_lite-0.8.1.tar.gz
Algorithm Hash digest
SHA256 720d83afbc8b99282cf0b2b43521772b07cf4a6ec706e74ddd6dd7a5dbab7405
MD5 307079a0f075d71637441e0a24445bb0
BLAKE2b-256 ec0c9c8c4097f1d949ec36bf2fd6302ad6e8f84dc06255b18c425fae737e9ca7

See more details on using hashes here.

Provenance

The following attestation bundles were made for repo_sentinel_lite-0.8.1.tar.gz:

Publisher: release.yml on stacknil/repo-sentinel-lite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file repo_sentinel_lite-0.8.1-py3-none-any.whl.

File metadata

File hashes

Hashes for repo_sentinel_lite-0.8.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0a949a4d00c6e6ae37eba60a6cb74e4e15bc3ec5fce2f1d4c99aa0ef309b36e3
MD5 1353d49caa84f7ed501b714d430c0b06
BLAKE2b-256 cab7047cee1278c80ef585065f0359f631692d2e4314af6819e4112bc861fed5

See more details on using hashes here.

Provenance

The following attestation bundles were made for repo_sentinel_lite-0.8.1-py3-none-any.whl:

Publisher: release.yml on stacknil/repo-sentinel-lite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.8.1 This release

2 files

0.7.1

2 files

0.7.0

2 files

0.6.3

2 files

0.6.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page