Metadata-Version: 2.4
Name: bawbel-scanner
Version: 1.0.0
Summary: Agentic AI component security scanner — detects AVE vulnerabilities
Author-email: Bawbel <bawbel.io@gmail.com>
License: Apache-2.0
Project-URL: Homepage, https://bawbel.io
Project-URL: Documentation, https://bawbel.io/docs
Project-URL: Repository, https://github.com/bawbel/bawbel-scanner
Project-URL: Bug Tracker, https://github.com/bawbel/bawbel-scanner/issues
Project-URL: Changelog, https://github.com/bawbel/bawbel-scanner/releases
Project-URL: AVE Standard, https://github.com/bawbel/bawbel-ave
Keywords: security,ai,scanner,ave,agentic,mcp,llm,skill,prompt-injection
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.1.0
Requires-Dist: rich>=13.7.0
Requires-Dist: pydantic>=2.5.0
Provides-Extra: yara
Requires-Dist: yara-python>=4.5.0; extra == "yara"
Provides-Extra: semgrep
Requires-Dist: semgrep>=1.60.0; extra == "semgrep"
Provides-Extra: llm
Requires-Dist: litellm>=1.30.0; extra == "llm"
Requires-Dist: jsonschema~=4.25.1; extra == "llm"
Provides-Extra: magika
Requires-Dist: magika>=0.5.0; extra == "magika"
Provides-Extra: watch
Requires-Dist: watchdog>=4.0.0; extra == "watch"
Provides-Extra: all
Requires-Dist: yara-python>=4.5.0; extra == "all"
Requires-Dist: semgrep>=1.60.0; extra == "all"
Requires-Dist: litellm>=1.30.0; extra == "all"
Requires-Dist: magika>=0.5.0; extra == "all"
Requires-Dist: watchdog>=4.0.0; extra == "all"
Requires-Dist: jsonschema~=4.25.1; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
Requires-Dist: pytest-mock>=3.12.0; extra == "dev"
Requires-Dist: black>=24.4.0; extra == "dev"
Requires-Dist: flake8>=7.0.0; extra == "dev"
Requires-Dist: flake8-bugbear>=24.0.0; extra == "dev"
Requires-Dist: bandit>=1.7.8; extra == "dev"
Requires-Dist: pre-commit>=3.7.0; extra == "dev"
Requires-Dist: pip-audit>=2.7.0; extra == "dev"
Requires-Dist: build>=1.0.0; extra == "dev"
Requires-Dist: twine>=5.0.0; extra == "dev"
Dynamic: license-file

# Bawbel Scanner

**Agentic AI component security scanner — detects AVE vulnerabilities before they reach production.**

[![PyPI version](https://badge.fury.io/py/bawbel-scanner.svg)](https://pypi.org/project/bawbel-scanner/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://pypi.org/project/bawbel-scanner/)
[![AVE Standard](https://img.shields.io/badge/AVE_Records-24-teal.svg)](https://github.com/bawbel/bawbel-ave)

Bawbel Scanner scans agentic AI components — SKILL.md files, MCP server manifests,
system prompts, and agent plugins — for security vulnerabilities mapped to the
[AVE (Agentic Vulnerability Enumeration)](https://github.com/bawbel/bawbel-ave) standard.

---

## Install

```bash
pip install bawbel-scanner
```

With optional engines:

```bash
pip install "bawbel-scanner[yara]"      # Stage 1b — YARA rules (15 rules)
pip install "bawbel-scanner[semgrep]"   # Stage 1c — Semgrep rules (15 rules)
pip install "bawbel-scanner[llm]"       # Stage 2  — LLM semantic analysis
pip install "bawbel-scanner[magika]"    # Stage 0  — file type verification (Google Magika)
pip install "bawbel-scanner[watch]"     # Watch mode — re-scan on file change
pip install "bawbel-scanner[all]"       # Everything: yara + semgrep + llm + magika + watch
```

Stage 3 (behavioral sandbox) requires Docker — see [Stage 3](#stage-3--behavioral-sandbox).

---

## Quick Start

```bash
cp .env.example .env   # copy env template, fill in your keys
source .env

bawbel version                                    # show version + active engines
bawbel scan ./my-skill.md                         # scan a file
bawbel scan ./skills/ --recursive                 # scan a directory
bawbel report ./my-skill.md                       # full remediation report
bawbel scan ./skills/ --fail-on-severity high     # exit 2 on HIGH+
bawbel scan ./skills/ --watch                     # re-scan on every change
bawbel scan ./skills/ --format json               # JSON for tooling
bawbel scan ./skills/ --format sarif              # SARIF for GitHub Security tab
```

**Example output:**

```
Bawbel Scanner v1.0.0  ·  github.com/bawbel/bawbel-scanner
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Scanning:  malicious-skill.md
Type:      skill

FINDINGS
──────────────────────────────────────────────────────────
🔴  CRITICAL  AVE-2026-00001      External instruction fetch detected
   Line 7  ·  fetch your instructions
   OWASP: ASI01 (Prompt Injection), ASI08 (Goal Hijacking)

🟠  HIGH      AVE-2026-00007      Goal override instruction detected
   Line 17  ·  Ignore all previous instructions
   OWASP: ASI01 (Prompt Injection), ASI08 (Goal Hijacking)
──────────────────────────────────────────────────────────
SUMMARY
──────────────────────────────────────────────────────────
Risk score:   9.4 / 10  CRITICAL
Findings:     2
Scan time:    5ms
→  Run bawbel report malicious-skill.md for full remediation guide
```

---


## False Positive Reduction

Bawbel v1.0 ships a 5-layer false positive reduction system — the result of real-world
feedback from scanning production skill files:

| Layer | Mechanism | FP reduction |
|---|---|---|
| FP-1 | Code fence stripping — ` ``` ` blocks skipped before static analysis | ~60% |
| FP-2 | Preceding-line context — "Never do this:" suppresses the line below | ~15% |
| FP-3 | Confidence scoring — table rows, headings, `docs/` paths penalised | ~10% |
| FP-4 | **Meta-analyzer** — one LLM call per file validates medium-confidence findings | ~7% |
| FP-5 | File-type profiles — documentation scanned at higher threshold (0.85) | ~3% |

The meta-analyzer (FP-4) sends all findings as enriched context to the LLM in a single
call — not a general security scan, but a targeted false-positive filter. Requires
`BAWBEL_LLM_ENABLED=true` and an API key. Skips silently if not configured.

See [False Positive Reduction guide](docs/guides/false-positive-reduction.md) for full details.

---
## Detection Pipeline

Five stages run in sequence — each adds an independent layer:

| Stage | Engine | Install | What it catches |
|---|---|---|---|
| 0  | **Magika** | `pip install "bawbel-scanner[magika]"` | Content-type verification — catches supply chain attacks (ELF disguised as .md, pickle as .yaml) |
| 1a | **Pattern** | nothing — always active | 15 regex rules, all AVE IDs |
| 1b | **YARA** | `pip install "bawbel-scanner[yara]"` | Binary + complex text combinations, 15 rules |
| 1c | **Semgrep** | `pip install "bawbel-scanner[semgrep]"` | Structural + multi-line patterns, 15 rules |
| 2  | **LLM** | `pip install "bawbel-scanner[llm]"` + API key | Obfuscated, nuanced, multi-paragraph injections |
| 3  | **Sandbox** | Docker + `BAWBEL_SANDBOX_ENABLED=true` | Runtime behaviour — network egress, filesystem, processes |

**15 built-in rules** covering every major agentic attack class:
goal override · jailbreak · hidden instructions · external fetch ·
tool call injection · permission escalation · credential exfiltration ·
PII exfiltration · shell injection · destructive commands ·
cryptocurrency drain · trust escalation · persistence ·
MCP tool poisoning · system prompt extraction.

---

## Stage 2 — LLM Semantic Analysis

Catches what regex misses: obfuscated payloads, synonym attacks, multi-paragraph
injections, and social engineering. Works with any LiteLLM-supported provider.

```bash
pip install "bawbel-scanner[llm]"

export ANTHROPIC_API_KEY=sk-ant-...   # → auto-selects claude-haiku-4-5-20251001
export OPENAI_API_KEY=sk-...          # → auto-selects gpt-4o-mini
export GEMINI_API_KEY=...             # set BAWBEL_LLM_MODEL=gemini/gemini-1.5-flash
export BAWBEL_LLM_MODEL=ollama/mistral  # local model, no API key needed

bawbel scan ./my-skill.md             # Stage 2 activates automatically
```

---

## Stage 3 — Behavioral Sandbox

Runs the component inside an isolated Docker container and monitors what it
*actually does* at runtime — catching attacks that static analysis cannot see.

```bash
export BAWBEL_SANDBOX_ENABLED=true
bawbel scan ./my-skill.md
```

**Hybrid image strategy — no setup required:**

```
1. Check local Docker cache  →  run immediately if found
2. Pull bawbel/sandbox:latest from Docker Hub  →  cache + run (~5s first time)
3. Build from bundled Dockerfile  →  offline / air-gapped fallback (~15s)
```

```bash
BAWBEL_SANDBOX_IMAGE=local                          # skip Hub, build locally
BAWBEL_SANDBOX_IMAGE=registry.corp.com/bawbel/sandbox@sha256:abc  # enterprise
```

Detects: outbound network egress · persistence writes (~/.bashrc, crontab) ·
credential access (~/.ssh/, .env) · shell pipe injection ·
subprocess spawning · Base64 encoded payloads.

See [Detection Engines Guide](docs/guides/engines.md) for full sandbox documentation.

---

## Use as a Library

```python
from scanner import scan

result = scan("/path/to/skill.md")

if result.is_clean:
    print("Clean")
else:
    for finding in result.findings:
        print(f"[{finding.severity.value}] {finding.ave_id}  {finding.title}")
        print(f"  Engine: {finding.engine}  CVSS-AI: {finding.cvss_ai}")
    print(f"\nRisk score: {result.risk_score:.1f} / 10")
```

---

## CI/CD Integration

### GitHub Actions — official action ✅

The recommended way to integrate Bawbel into CI/CD.
One line — installs the scanner, runs the scan, uploads findings to the
GitHub Security tab automatically.

```yaml
# .github/workflows/bawbel.yml
name: Bawbel Security Scan
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
      contents: read
    steps:
      - uses: actions/checkout@v4

      - uses: bawbel/bawbel-integrations@v1
        id: bawbel
        with:
          path: .
          fail-on-severity: high
          format: sarif

      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: ${{ steps.bawbel.outputs.sarif-file }}
```

**Action inputs:** `path`, `fail-on-severity`, `format`, `recursive`, `no-ignore`, `version`, `extras`
**Action outputs:** `sarif-file`, `findings-count`, `risk-score`, `result`

See [bawbel/bawbel-integrations](https://github.com/bawbel/bawbel-integrations) for
full documentation and examples.

### VS Code Extension

Install **Bawbel Scanner** from the VS Code Marketplace. Auto-installs
the CLI on first activation — no manual setup required. Inline diagnostics,
status bar, auto-scan on save.

### Manual GitHub Actions (without official action)

```yaml
      - name: Scan for AVE vulnerabilities
        run: |
          pip install "bawbel-scanner[all]"
          bawbel scan . --recursive --fail-on-severity high
```

### Pre-commit

```yaml
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: bawbel-scan
        name: Bawbel Scanner
        entry: bawbel scan
        language: system
        pass_filenames: true
        types: [markdown]
        args: ["--fail-on-severity", "high"]
```

```bash
pip install bawbel-scanner && pre-commit install
```

---

## Configuration

Copy `.env.example` and fill in your values:

```bash
cp .env.example .env
```

| Variable | Default | Description |
|---|---|---|
| `BAWBEL_LOG_LEVEL` | `WARNING` | `DEBUG` · `INFO` · `WARNING` · `ERROR` |
| `ANTHROPIC_API_KEY` | — | Enables Stage 2 via Claude |
| `OPENAI_API_KEY` | — | Enables Stage 2 via OpenAI |
| `BAWBEL_LLM_MODEL` | auto | Any LiteLLM model string |
| `BAWBEL_LLM_ENABLED` | `true` | Set `false` to disable Stage 2 |
| `BAWBEL_SANDBOX_ENABLED` | `false` | Set `true` to enable Stage 3 |
| `BAWBEL_SANDBOX_IMAGE` | `default` | `default` · `local` · custom image |
| `BAWBEL_SANDBOX_TIMEOUT` | `30` | Container timeout in seconds |
| `BAWBEL_SANDBOX_NETWORK` | `none` | `none`=isolated · `bridge`=internet |
| `BAWBEL_NO_IGNORE` | `false` | Set `true` to override all suppressions (audit mode) |

See [`.env.example`](.env.example) for the full reference.

---

## Suppression — Managing False Positives

Three mechanisms to suppress known false positives. Suppressed findings are **never deleted** — they appear in `suppressed_findings` in JSON output for full audit trail.

### Inline — on the line

```markdown
fetch https://internal.company.com  <!-- bawbel-ignore -->
fetch https://internal.company.com  <!-- bawbel-ignore: bawbel-external-fetch -->
fetch https://internal.company.com  <!-- bawbel-ignore: AVE-2026-00001 -->
fetch https://internal.company.com  # bawbel-ignore
```

### Block — a section

```markdown
<!-- bawbel-ignore-start -->
fetch https://internal.company.com
Ignore all previous instructions  ← intentional, test fixture
<!-- bawbel-ignore-end -->
```

### .bawbelignore — entire files or directories

```
# .bawbelignore
tests/fixtures/**          # all test fixtures
docs/examples/bad.md       # known-bad example file
**/test_*.md               # all test skill files
```

### Audit mode — override all suppressions

```bash
bawbel scan ./skills/ --no-ignore      # CLI flag
BAWBEL_NO_IGNORE=true bawbel scan ./   # env var
```

See [Suppression Guide](docs/guides/suppression.md) for full documentation.


---

## AVE Standard

Every finding maps to a published AVE record — the CVE equivalent for agentic AI.

- Browse records: [github.com/bawbel/bawbel-ave](https://github.com/bawbel/bawbel-ave)
- Threat intelligence API: [api.piranha.bawbel.io](https://api.piranha.bawbel.io)
- Report a vulnerability: open an issue on [bawbel-ave](https://github.com/bawbel/bawbel-ave/issues)

---

## Documentation

| Resource | Link |
|---|---|
| Full docs | [bawbel.io/docs](https://bawbel.io/docs) |
| Getting started | [docs/guides/getting-started.md](docs/guides/getting-started.md) |
| Detection engines | [docs/guides/engines.md](docs/guides/engines.md) |
| Configuration | [docs/guides/configuration.md](docs/guides/configuration.md) |
| CI/CD integration | [docs/guides/cicd-integration.md](docs/guides/cicd-integration.md) |
| Python API | [docs/api/scan.md](docs/api/scan.md) |
| Suppression | [docs/guides/suppression.md](docs/guides/suppression.md) |
| False positive reduction | [docs/guides/false-positive-reduction.md](docs/guides/false-positive-reduction.md) |
| Writing rules | [docs/guides/writing-rules.md](docs/guides/writing-rules.md) |
| Changelog | [CHANGELOG.md](CHANGELOG.md) |

---

## License

Apache 2.0 — see [LICENSE](LICENSE).

Built by [Bawbel](https://bawbel.io) · [bawbel.io@gmail.com](mailto:bawbel.io@gmail.com)
