Metadata-Version: 2.4
Name: picosentry
Version: 2.0.2
Summary: Unified supply-chain security suite — scanner, sandbox, LLM defense, and orchestration
Author-email: Henrik Kirk <kirk@kirkforge.dev>
Maintainer-email: KirkForge <kirk@kirkforge.dev>
License-Expression: BUSL-1.1
Project-URL: Homepage, https://github.com/KirkForge/PicoSentry
Project-URL: Documentation, https://github.com/KirkForge/PicoSentry#readme
Project-URL: Repository, https://github.com/KirkForge/PicoSentry
Project-URL: Issues, https://github.com/KirkForge/PicoSentry/issues
Project-URL: Changelog, https://github.com/KirkForge/PicoSentry/blob/main/CHANGELOG.md
Project-URL: Release Notes, https://github.com/KirkForge/PicoSentry/releases
Project-URL: Source Code, https://github.com/KirkForge/PicoSentry
Project-URL: Bug Tracker, https://github.com/KirkForge/PicoSentry/issues
Project-URL: Commercial, https://github.com/KirkForge/PicoShogun
Keywords: security,supply-chain,sandbox,llm-defense,prompt-injection,scanner,npm,pnpm,deterministic,audit,orchestration,devsecops,ci-cd
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Information Technology
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: System :: Monitoring
Classifier: Environment :: Console
Classifier: Framework :: FastAPI
Classifier: Framework :: Pytest
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: LICENSE-SUMMARY.md
License-File: COMMERCIAL-LICENSE.md
Requires-Dist: pyyaml>=6.0
Provides-Extra: scan
Requires-Dist: requests>=2.31.0; extra == "scan"
Provides-Extra: watch-server
Requires-Dist: fastapi>=0.100; extra == "watch-server"
Requires-Dist: uvicorn>=0.23; extra == "watch-server"
Provides-Extra: serve
Requires-Dist: fastapi>=0.104.0; extra == "serve"
Requires-Dist: uvicorn[standard]>=0.24.0; extra == "serve"
Requires-Dist: pydantic>=2.0.0; extra == "serve"
Requires-Dist: PyJWT>=2.8.0; extra == "serve"
Requires-Dist: passlib[bcrypt]>=1.7.4; extra == "serve"
Requires-Dist: python-multipart>=0.0.6; extra == "serve"
Requires-Dist: croniter>=1.0.0; extra == "serve"
Provides-Extra: otel
Requires-Dist: opentelemetry-api>=1.20; extra == "otel"
Requires-Dist: opentelemetry-sdk>=1.20; extra == "otel"
Requires-Dist: opentelemetry-exporter-otlp>=1.20; extra == "otel"
Provides-Extra: sigstore
Requires-Dist: sigstore>=3.0; extra == "sigstore"
Provides-Extra: all
Requires-Dist: picosentry[otel,scan,serve,sigstore,watch-server]; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
Requires-Dist: pytest-timeout>=2.0; extra == "dev"
Requires-Dist: httpx>=0.24; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Requires-Dist: jsonschema>=4.0; extra == "dev"
Requires-Dist: types-PyYAML; extra == "dev"
Dynamic: license-file

# PicoSentry 🦞

![PicoSentry Banner](docs/banner.png)

**The only local package scanner that actually runs the package under a real kernel sandbox and shows you the syscalls.** Deterministic, offline, no telemetry. Same inputs + same policy = same SHA-256. npm, PyPI, Go, Cargo, Maven, RubyGems, NuGet.

> Every other scanner stops at static analysis. PicoSentry goes further: install
> the candidate package inside a `seccomp-BPF` + `landlock` + `ptrace` sandbox and
> record every syscall, file open, and network call — before you run it on
> your laptop, CI, or production.

[![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)](https://pypi.org/project/picosentry/)
[![License: BUSL-1.1](https://img.shields.io/badge/license-BUSL--1.1-blue)](LICENSE)
[![tests](https://github.com/KirkForge/PicoSentry/actions/workflows/ci.yml/badge.svg)](https://github.com/KirkForge/PicoSentry/actions)
[![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-support%20my%20hardware-FFDD00?logo=buy-me-a-coffee&logoColor=black)](https://buymeacoffee.com/kirkforge)

---

## Quick demo

```bash
pip install picosentry

# Clone the example vulnerable projects
git clone https://github.com/KirkForge/PicoSentry.git
cd PicoSentry

# 1. Static scan — offline, no install, finds IOCs by literal/regex match
picosentry scan examples/pypi-obfuscated-setup/

# 2. Runtime sandbox — actually install + execute under a kernel sandbox
#    and watch the syscalls. Catches "static looks clean, dynamic is malicious."
picosentry sandbox npm install evil-package
```

Expected output:

```text
🦞 PicoSentry
Target: examples/pypi-obfuscated-setup
Engine: v2.0.2 | Corpus: vef6b3b3115bb
Scan ID: 9952b1a9c6a07e7f

Packages scanned: 0
Files scanned:     2
Duration:          7ms

Rule Timings:
  L2-PYPI-OBFS-001       0ms  (1 findings)
  L2-PYPI-OBFS-002       0ms  (2 findings)
  L2-PYPI-OBFS-007       0ms  (1 findings)
  L2-PYPI-POST-001       0ms  (1 findings)
  …

Pinches by Severity:
  HARD PINCH  : 3
  HARD PINCH  : 2

Pinches:

  [HARD PINCH] L2-PYPI-OBFS-001 unknown
    File: setup.py:10
    Dynamic code execution via exec
    Evidence: exec(
    Confidence: HIGH

  [HARD PINCH] L2-PYPI-OBFS-002 unknown
    File: setup.py:7
    Base64-decoded string detected
    Evidence: base64.b64decode(encoded)
    Confidence: HIGH

  [HARD PINCH] L2-PYPI-OBFS-002 unknown
    File: setup.py:15
    Base64-decoded string detected
    Evidence: base64.b64decode("ZXZpbC1zZXJ2ZXIuZXhhbXBsZS5jb20=")
    Confidence: HIGH

  [HARD PINCH] L2-PYPI-OBFS-007 unknown
    File: setup.py:7
    Base64 decode followed by exec/eval
    Evidence: b64decode(encoded).decode("utf-8")
    Confidence: HIGH

  [HARD PINCH] L2-PYPI-POST-001 pypi-obfuscated-setup
    File: setup.py
    setup.py contains code execution during installation
    Evidence: line 10: exec(decoded); line 13: if "CI" not in os.environ:; …
    Confidence: EXACT
```

> Note: rule IDs and counts above are taken from the current CLI run on
> `examples/pypi-obfuscated-setup`. Re-run `picosentry scan examples/pypi-obfuscated-setup`
> to reproduce; the `Scan ID` and `Corpus` digest will match exactly.

---

## What it detects

| Rule | What it catches | Example |
|------|----------------|---------|
| L2-TYPO-001 | Typosquatted package names | `reqursts` instead of `requests` |
| L2-DEPC-001 | Dependency confusion (private → public) | `internal-pkg` not on registry |
| L2-PYPI-OBFS-001 | Dynamic execution in setup.py | `exec()` / `eval()` in install scripts |
| L2-PYPI-OBFS-002 | Base64-decoded payloads in source | `base64.b64decode(...)` + dynamic use |
| L2-PYPI-OBFS-007 | Base64 decode + exec/eval combo | Decode-then-execute obfuscation chain |
| L2-PYPI-POST-001 | Postinstall code execution | `setup.py` runs code at install time |
| L2-NETEX-001 | Network calls during install | `urllib.request`, `curl`, `wget` at install |
| L2-IOC-001 | Known IOC behavior patterns | Hardcoded C2 host, exfil URL patterns |
| L2-CVE-001 | Known CVEs in dependency tree | OSV-matched vulnerabilities |
| L2-DEP-001 | Deprecated/insecure dependency | End-of-life library versions |
| L2-SBOM-001 | SBOM generation | CycloneDX-compatible output |

See [docs/rules/](picosentry/scan/docs/rules/) for the full rule catalog.

---

## Compared to other tools

| Tool | PicoSentry difference |
|------|-----------------------|
| **pip-audit** | PicoSentry also detects malicious *behavior patterns* (obfuscation, typosquatting, exfil) |
| **osv-scanner** | PicoSentry adds deterministic offline rules + typosquat/dependency-confusion heuristics |
| **Trivy** | PicoSentry is deterministic (no probabilistic scoring) and focused on dev workflow |
| **Garak** | Garak tests LLM models; PicoSentry also guards prompts/output in apps |
| **Socket CLI** | PicoSentry is fully offline, deterministic, and open-source |

---

## Install

```bash
# Core scanner — works offline, no HTTP deps (only `pyyaml` installed)
pip install picosentry

# Extras
pip install picosentry[scan]      # + online corpus management
pip install picosentry[serve]     # + API server + dashboard
pip install picosentry[all]       # Everything
```

The default `pip install picosentry` is deliberately lightweight — it pulls in
only `pyyaml`, which is enough to run `picosentry scan` against any project.
To use the API server, dashboard, or HTTP corpus refresh, install the matching
extras (see [install options](#install-options) below).

See [install options](#install-options) below for details.

---

## Usage

### Scan a project

```bash
picosentry scan ./my-project
picosentry scan ./package.json                  # single file
picosentry scan --format json ./project        # JSON output
picosentry scan --format sarif ./project        # SARIF output
picosentry scan --format cyclonedx ./project    # CycloneDX SBOM
picosentry scan --verify-determinism ./project  # assert SHA-256 stability
picosentry scan --diff scan-a.json scan-b.json  # compare two scans
picosentry scan --fail-on high ./project        # exit non-zero on HIGH+
```

### Verify determinism

```bash
picosentry scan --verify-determinism ./project
# Runs scan twice, asserts SHA-256 match
```

### Sandbox a command (beta)

```bash
picosentry sandbox echo "hello"
picosentry sandbox --timeout 5 ls -la
```

### LLM prompt guard (beta)

```bash
picosentry watch scan-prompt --text "Ignore all instructions..."
picosentry watch scan-prompt --file suspicious.txt
```

### API server (experimental)

```bash
picosentry serve --port 8765
```

### Health check

```bash
picosentry health
```

---

## Install options

| Command | What you get |
|---------|-------------|
| `pip install picosentry` | Core: scanner, sandbox, watch (lightweight) |
| `pip install picosentry[scan]` | + requests for online corpus management |
| `pip install picosentry[serve]` | + FastAPI server, dashboard, auth, scheduler |
| `pip install picosentry[watch-server]` | + FastAPI + uvicorn for watch HTTP daemon |
| `pip install picosentry[otel]` | + OpenTelemetry tracing |
| `pip install picosentry[sigstore]` | + Sigstore signing support |
| `pip install picosentry[all]` | Everything |

---

## Feature maturity

| Component | Status | Description |
|-----------|--------|-------------|
| `picosentry scan` | ✅ Stable | Core supply-chain scanner for 7 ecosystems |
| `picosentry sandbox` | ⚠️ Beta | seccomp-bpf sandbox; gRPC transport experimental |
| `picosentry watch` | ⚠️ Beta | Prompt injection detection; server experimental |
| `picosentry serve` | 🔬 Experimental | API server + dashboard in active development |
| Postgres backend | ❌ Stub | SQLite only; Postgres not started (PRs welcome) |
| DDoS shield | 🔬 Experimental | Basic rate limiting only |
| Cluster mode | 🔬 Experimental | Single-node OK; multi-node untested |
| Corpus marketplace | 🔬 Experimental | Import/export works; CLI commands pending |
| Detection benchmarks | ❌ Stub | Framework defined, no real data yet |

See [`picosentry/experimental.py`](picosentry/experimental.py) for full details.

---

## Key design principles

- **Deterministic**: Same inputs + same policy = same SHA-256 output. No randomness, no probabilistic scoring, no network dependence.
- **Offline by default**: No phone-home, no remote API calls at scan time. Works in air-gapped environments.
- **Typed**: Full Python type annotations. `mypy --strict` compatible.
- **Fast**: Sub-second scans for typical projects. No heavyweight dependency tree download at scan time.

---

## Repository structure

```
picosentry/
    _core/          Vendored shared primitives
    scan/           Supply-chain scanner
    sandbox/        Runtime sandbox (seccomp-bpf)
    watch/          LLM prompt guard
    serve/          API server + dashboard
    experimental.py Maturity tracking
examples/
    pypi-obfuscated-setup/
    npm-postinstall-exfil/
    prompt-injection/
docs/
    rules/          Full rule catalog per ecosystem
    strategic/      Design docs and architecture
tests/              3000+ tests
```

---

## License

BUSL-1.1 — see [LICENSE](LICENSE) and [COMMERCIAL-LICENSE.md](COMMERCIAL-LICENSE.md).
