| Version | Supported |
|---|---|
| 0.16.x | ✅ |
| 0.15.x | ✅ |
| < 0.15 | ❌ |
PicoSentry is pre-1.0. Only the latest release receives security fixes.
Do not report security vulnerabilities through public GitHub issues.
Instead, open a private vulnerability report on GitHub: https://github.com/KirkForge/PicoSentry/security/advisories/new
Include:
- PicoSentry version (
picosentry version) - Python version and OS
- Description of the vulnerability
- Steps to reproduce
- Potential impact (e.g., "could allow bypass of L2-POST-001 detection")
- Acknowledgment: within 48 hours
- Initial assessment: within 5 business days
- Fix or mitigation: depends on severity
- Coordinated disclosure: we ask for 90 days before public disclosure
- Credit: researchers receive credit in the changelog and advisory unless they request anonymity
- Advisories: published as GitHub Security Advisories and in CHANGELOG.md
PicoSentry's core thesis is deterministic scanning: same inputs + same corpus = same output, every time.
If you find a case where PicoSentry produces different findings on identical inputs (without corpus changes), that is a high-severity bug, even if no security finding is missed. Report it through the same channel.
Verify determinism with:
picosentry scan ./project --format json -o a.json
picosentry scan ./project --format json -o b.json
picosentry diff a.json b.json
# Should output: "✓ Scans are IDENTICAL"PicoSentry follows a fail-closed security posture by default:
| Setting | Default | Fail-closed behavior |
|---|---|---|
corpus_require_signature |
True |
Unsigned corpus packs are rejected |
verify_content() on unsigned |
False |
Unsigned bundles fail verification |
| OIDC auth on missing PyJWT | Deny | No unsigned-token fallthrough |
| OIDC auth on JWKS fetch failure | Deny | No bypass on IdP outage |
| Daemon bind address | 127.0.0.1 |
No accidental network exposure |
| Scan path resolution | Restricted | Rejects absolute paths, .., and paths outside PICOSENTRY_SCAN_ROOT |
| Typosquat short names | ≤4 chars: MEDIUM/LOW max | Short-name matches never break CI with --fail-on high |
If you find a case where PicoSentry fails open where it should fail closed, that is a security bug. Report it through the same channel.
The typosquat detector uses Levenshtein edit distance against a corpus of 327 popular npm packages. To reduce false-positive noise:
- Short package names (≤4 chars) emit at most MEDIUM severity for distance-1, LOW for distance-2
- Length-ratio scoring prevents coincidental similarity from being rated HIGH
- Only distance-1 matches with ≥0.8 length ratio on names ≥5 chars are rated HIGH
If you encounter a legitimate package flagged as a typosquat, use the ignore_packages config:
# .picosentry.yml
ignore_packages:
- my-internal-package # legitimately named similar to a top packageEvery PicoSentry release is signed with Sigstore. Verify any release artifact:
./scripts/verify_release.sh v0.16.1This confirms the artifact was built in CI by the release.yml workflow and has not been tampered with.
PicoSentry has zero hard runtime dependencies. The only dependencies are:
pyyaml(pnpm-lock.yaml parser, optional — only needed for pnpm projects)pytest/pytest-cov/mypy/ruff(dev only)
This minimal attack surface is by design. We will not add runtime dependencies without strong justification.
SCAAT.md provides a full mapping of detection rules to supply-chain attack vectors. If you believe a rule has a false negative, include the SCAAT vector reference in your report.