Skip to main content

super-scanner

An extensible, orchestration-first security scanning base package for Python. super-scanner wraps best-in-class open-source scanning engines (Semgrep, Bandit, Trivy, Grype, OSV-Scanner, pip-audit, Checkov, detect-secrets, gitleaks, ModelScan, Prowler, …) behind one typed plugin API and one normalized findings model, so you can run an AWS CSPM sweep, a Semgrep code scan, an SCA/dependency scan, a container image scan, or a secrets scan in three lines of Python — and get back deterministic, deduplicated, SARIF/OCSF/CycloneDX-ready findings. It orchestrates; it does not reimplement.

  • Runs everywhere, sends nothing. No telemetry, no analytics, no "phone home" and the core makes zero outbound network calls. Fully offline/air-gapped capable.
  • Base package to build on. A lean, permissively-licensed (Apache-2.0) pure-Python core. Add engines, cloud providers, and output formats via entry_points — no core changes, no forking.
  • Everything configurable. Layered config (defaults < file < env < kwargs/CLI), per-engine settings, rules locations, offline mode, fail-on thresholds, baselines, and suppressions.

Install

pip install super-scanner                 # lean core (no scanner engines)
pip install "super-scanner[code]"          # + Semgrep (SAST)
pip install "super-scanner[code-bandit]"   # + Bandit (Python SAST)
pip install "super-scanner[secrets]"       # + detect-secrets
pip install "super-scanner[sca-python]"    # + pip-audit
pip install "super-scanner[iac]"           # + Checkov
pip install "super-scanner[aws]"           # + Prowler (AWS CSPM)
pip install "super-scanner[ci]"            # curated: code+secrets+sca+container+iac

Some engines are Go/native binaries (Trivy, Grype, Syft, OSV-Scanner, gitleaks, nuclei, cosign, Prowler CLI…). Those are never shipped as Python packages — but you don't have to hunt them down: super-scanner can install them for you (see below). super-scanner doctor tells you exactly what's missing.

Requirements: Python ≥ 3.10. Pure-Python universal wheel; no compiled extensions in the core.

Auto-installing scanner tools

super-scanner ships an installer driven by per-tool configs in install_configs/ (one <tool>.yaml per tool, e.g. semgrep.yaml, trivy.yaml, prowler.yaml). It picks the best method available on your machine (pipx/pip/brew/go/script), respecting offline mode.

super-scanner setup                       # show what's installed / missing / how to get it
super-scanner install trivy grype nuclei  # install specific tools
super-scanner install --engines semgrep,osv-scanner   # install tools backing these engines
super-scanner install --all               # install every tool with a config
super-scanner install trivy --dry-run     # print the exact command, install nothing
super-scanner scan container nginx:latest --install-missing   # install then scan

# repo bootstrap (venv + package + optional tools):
scripts/bootstrap.sh --tools "semgrep trivy grype osv-scanner"

Each config lists methods per platform; override the method with --prefer brew|pip|pipx|go|script, or point at a specific binary via [tool.super-scanner.engines.<tool>].binary_path. Nothing is installed during a normal scan unless you pass --install-missing. Add your own tools by dropping a <tool>.yaml into an install_configs/ directory (or set $SUPER_SCANNER_INSTALL_CONFIGS).


Quick start — a few lines of Python

from super_scanner import scan

# Static code analysis (Semgrep + Bandit)
report = scan.code("./src")
print(report.summary_line())               # critical=0 high=2 medium=1 ... total=5
report.to_sarif("out.sarif")               # SARIF 2.1.0
report.raise_for_status(fail_on="high")    # raises if any finding >= HIGH
from super_scanner import scan

report = scan.container("nginx:latest")    # Trivy + Grype
report = scan.sca("./")                    # OSV-Scanner / pip-audit
report = scan.secrets("./")                # detect-secrets / gitleaks
report = scan.iac("./infra")               # Checkov (+ hadolint/tfsec/kics/cfn-lint)
report = scan.model("./model.pkl")         # ModelScan (malicious model files)
report = scan.aws()                        # Prowler CSPM (raises NoCredentialsError if no creds)

# M1/M2 domains — same one-call shape:
report = scan.sbom("./")                   # Syft SBOM
report = scan.k8s("./manifests")           # Kubescape / kube-bench
report = scan.license("./")                # ScanCode license compliance
report = scan.malpkg("requirements.txt")   # GuardDog malicious-package detection
report = scan.pii("./data")                # Presidio PII discovery
report = scan.malware("./", rules=["rules.yar"])   # YARA
report = scan.provenance("img@sha256:...") # Cosign signature/SLSA verification
report = scan.scm("github.com/org/repo")   # OpenSSF Scorecard

# Active scanners (require authorization for non-local targets):
report = scan.dast("http://localhost:8080")            # nuclei
report = scan.network("10.0.0.0/24", authorized=True)  # nmap
report = scan.tls("example.com", authorized=True)      # sslyze
report = scan.api("./openapi.json", authorized=True)   # schemathesis

Async & streaming

import anyio
from super_scanner import scan, ascan

report = anyio.run(lambda: ascan("code", "./src"))     # async
for finding in scan.code.stream("./src"):              # stream results as they arrive
    print(finding.severity.name, finding.rule.id, finding.locations[0].display())

Multi-engine / multi-target builder

from super_scanner import Scan

report = (
    Scan()
    .with_engines("semgrep", "bandit", "detect-secrets")
    .on("./src")
    .config(offline=True, fail_on="high")
    .options(rules=["p/owasp-top-ten", "./rules/custom.yml"])
    .run()
)

Working with findings

report.summary()                 # {"critical": 0, "high": 2, ..., "total": 5}
report.dedup()                   # collapse same-finding across engines (auto on by default)
report.diff(baseline)            # new vs unchanged vs absent
report.apply_suppressions(supp)  # drop suppressed findings
report.fail_on("high")           # count of findings >= HIGH
report.exit_code(fail_on="high") # deterministic CI exit code

# every output format:
report.to_json(); report.to_sarif(); report.to_cyclonedx(); report.to_asff()
report.to_gitlab(); report.to_junit(); report.to_csv(); report.to_html(); report.to_table()
report.to_ocsf()                 # AWS/Prowler findings only in M0

Command line

super-scanner doctor                    # which engines are available + how to install missing ones
super-scanner list-engines              # JSON: every engine, status, license, integration
super-scanner scan code ./src --engines semgrep,bandit --fail-on high --format sarif --output-dir ./reports
super-scanner scan container nginx:latest --format json
super-scanner scan secrets ./ --format table
super-scanner baseline create code ./src --out .super-scanner.baseline
super-scanner scan code ./src --baseline .super-scanner.baseline --new-only --fail-on medium
super-scanner suppress --out .super-scanner-suppressions.json
super-scanner sbom ./ --format cyclonedx
super-scanner db gc                     # clean stale caches / temp roots

Exit codes (format-independent): 0 clean/within-threshold · 1 findings exceed --fail-on · 2 usage/config error · 3 engine execution error · 4 partial results · 5 authorization required but not attested. --exit-zero forces report-only.


Configuring engines

Config precedence (lowest → highest): built-in defaults → config file → environment variables → Python kwargs / CLI flags.

Put a [tool.super-scanner] table in pyproject.toml, or a dedicated super-scanner.toml:

[tool.super-scanner]
offline = false
redact = true            # redact discovered secrets (on by default)
telemetry = false        # OFF by default; nothing is ever sent anywhere
fail_on = "high"

[tool.super-scanner.engines.semgrep]
enabled = true
timeout = 900
# Rules location: registry packs, local rule files, and/or rule dirs.
# Overridable per-call via scan.code(..., rules=[...]) and $SUPER_SCANNER_SEMGREP_CONFIG.
config = ["p/security-audit", "./rules/custom.yml", "./rules/org-pack/"]
offline_rules_path = "./vendor/semgrep-rules"   # used when offline = true

[tool.super-scanner.engines.semgrep.settings]
metrics = "off"          # default; forced off when offline
jobs = 4
max_memory_mb = 4000
exclude = ["tests/", "vendor/"]

[tool.super-scanner.engines.trivy]
binary_path = "/opt/bin/trivy"
db_repository = "registry.internal/trivy-db"

[tool.super-scanner.plugins]
allowlist = ["my-org-scanner==1.4.*"]    # only load allowlisted third-party plugins
require_signed = false

Semgrep rules location — 4 ways, one precedence

  1. Python: scan.code("./src", rules=["p/owasp-top-ten", "./rules/custom.yml"])
  2. Env var: SUPER_SCANNER_SEMGREP_CONFIG="p/security-audit:./rules" (OS path-list separated)
  3. Config file: [tool.super-scanner.engines.semgrep].config = [...]
  4. Default: p/default online, or the pinned/vendored ruleset when offline.

Environment kill-switches (authoritative)

Variable Effect
SUPER_SCANNER_OFFLINE=true No network; engines run in offline mode
SUPER_SCANNER_TELEMETRY=false Telemetry off (default) — nothing sent anywhere
SUPER_SCANNER_REDACT=true Redact discovered secrets from all output/logs
SUPER_SCANNER_NETWORK_EGRESS=false Subprocess engines run network-off
SUPER_SCANNER_PLUGIN_ALLOWLIST="dist-a,dist-b" Only load allowlisted plugins

An env value that is safer always wins over a config-file value.


Privacy & offline use

  • No telemetry, ever, by default. The core performs no outbound network calls. super-scanner scan ... --offline (or offline=true) guarantees engines run without network access, and forces semgrep --metrics=off regardless of any override.
  • Secrets are redacted. Detected secrets are stored as SHA-256 hashes (never plaintext) and scrubbed from logs.
  • Nothing executes scanned code. SAST/model scanning is static; the scanned model is never loaded/imported.

This makes super-scanner safe to run inside any company's air-gapped or regulated environment.


Extending it — build your own scanner on top

Add an engine in your own package with zero changes to super-scanner:

# my_pkg/engine.py
from super_scanner.engines.base import Capability, Engine, Integration
from super_scanner.model import Finding, Rule, Severity, PhysicalLocation

class MyEngine(Engine):
    id = "my-engine"
    name = "My Engine"
    domain = "sast"

    def capabilities(self):
        return Capability(target_types=frozenset({"path"}), integration=Integration.LIBRARY)

    def scan(self, target, ctx):
        yield Finding(engine=self.id, domain="sast", rule=Rule(id="my.rule"),
                      severity=Severity.HIGH, message="found it",
                      locations=(PhysicalLocation(uri=str(target)),))
# my_pkg/pyproject.toml
[project.entry-points."super_scanner.engines"]
my-engine = "my_pkg.engine:MyEngine"

pip install my-pkg and it shows up in super-scanner doctor, scan("sast", ...), and everywhere else. Reporters (super_scanner.reporters) and cloud providers (super_scanner.providers) extend the same way.


What's covered

30 engines across 19 domains — all behind the same one-call API, all installable via super-scanner install.

Domain Engines Extra / tool
SAST (code) Semgrep, Bandit [code], [code-bandit]
SCA (deps) OSV-Scanner, pip-audit [sca], [sca-python]
Secrets detect-secrets, gitleaks, trufflehog [secrets]
Container image Trivy, Grype, Dockle [container] (binaries)
SBOM Syft (+ Trivy/Grype) binary
IaC Checkov, hadolint, tfsec, KICS, cfn-lint [iac], [iac-lint]
Kubernetes / host Kubescape, kube-bench [k8s] (binaries)
GenAI model files ModelScan [genai]
Cloud CSPM Prowler (AWS), ScoutSuite (multi-cloud) [aws], [aws-scoutsuite]
License ScanCode [license]
Malicious packages GuardDog [malpkg]
PII / data Presidio [pii]
Malware YARA [malware]
Provenance Cosign (sigstore/SLSA) [provenance] (binary)
SCM / CI posture OpenSSF Scorecard [scm] (binary)
DAST / web nuclei [web] (binary)
Network nmap [network] (binary)
TLS sslyze [tls]
API schemathesis [api]

Still on the roadmap: mobile (MobSF), CIEM/attack-path graphs, full cross-engine OCSF export, and live-cluster runtime (Falco). The plugin contract already supports them.

Metadata

Release files for super-scanner 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for super-scanner 0.0.2
File Size Uploaded Provenance Actions
super_scanner-0.0.2.tar.gz 108.6 kB With provenance Details for super_scanner-0.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for super-scanner 0.0.2
File Interpreter ABI Platform Actions
super_scanner-0.0.2-py3-none-any.whl Python 3 none any Details for super_scanner-0.0.2-py3-none-any.whl

Total release size: 252.8 kB

Release files / super_scanner-0.0.2.tar.gz

Download URL super_scanner-0.0.2.tar.gz
Size 108.6 kB
Tags Source
SHA-256 checksum
How to use checksums
da302a5eac85371f33f32ded6d22149ded0fe60ee9d670a94622891d5c3c62c0
BLAKE2b-256 checksum
How to use checksums
877e7490199d317405f5580959607a36cc3955de9da21e95659886b9eda22ca2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 8, 2026.

Transparency log

Release files / super_scanner-0.0.2-py3-none-any.whl

Download URL super_scanner-0.0.2-py3-none-any.whl
Size 144.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ddf9e999a86e459bf4ceab5d7c2e67404015061eeea5eaa27b8db19600c6292b
BLAKE2b-256 checksum
How to use checksums
f227dbc6e459f0bfac769405fc5a9d091dadb345a0a62a9aa3a807b1ae24997f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 8, 2026.

Transparency log

Security for super-scanner 0.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for super_scanner-0.0.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 8, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.2 This release

2 release files Full provenance

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