Extensible, orchestration-first security scanning base package
Project description
super-scanner
An extensible, orchestration-first security scanning base package for Python.
super-scannerwraps 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
- Python:
scan.code("./src", rules=["p/owasp-top-ten", "./rules/custom.yml"]) - Env var:
SUPER_SCANNER_SEMGREP_CONFIG="p/security-audit:./rules"(OS path-list separated) - Config file:
[tool.super-scanner.engines.semgrep].config = [...] - Default:
p/defaultonline, 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(oroffline=true) guarantees engines run without network access, and forcessemgrep --metrics=offregardless 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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file super_scanner-0.0.2.tar.gz.
File metadata
- Download URL: super_scanner-0.0.2.tar.gz
- Upload date:
- Size: 108.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da302a5eac85371f33f32ded6d22149ded0fe60ee9d670a94622891d5c3c62c0
|
|
| MD5 |
f19c7a49cc3113e55fab6f4444287080
|
|
| BLAKE2b-256 |
877e7490199d317405f5580959607a36cc3955de9da21e95659886b9eda22ca2
|
Provenance
The following attestation bundles were made for super_scanner-0.0.2.tar.gz:
Publisher:
workflow.yml on KarAshutosh/super-scanner
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
super_scanner-0.0.2.tar.gz -
Subject digest:
da302a5eac85371f33f32ded6d22149ded0fe60ee9d670a94622891d5c3c62c0 - Sigstore transparency entry: 2118486096
- Sigstore integration time:
-
Permalink:
KarAshutosh/super-scanner@f4f33c3cce1aab9e3c05db8fe54e539ebbb74dec -
Branch / Tag:
refs/heads/main - Owner: https://github.com/KarAshutosh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@f4f33c3cce1aab9e3c05db8fe54e539ebbb74dec -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file super_scanner-0.0.2-py3-none-any.whl.
File metadata
- Download URL: super_scanner-0.0.2-py3-none-any.whl
- Upload date:
- Size: 144.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ddf9e999a86e459bf4ceab5d7c2e67404015061eeea5eaa27b8db19600c6292b
|
|
| MD5 |
832ef0c8508afa82a092f2ccf292e1e0
|
|
| BLAKE2b-256 |
f227dbc6e459f0bfac769405fc5a9d091dadb345a0a62a9aa3a807b1ae24997f
|
Provenance
The following attestation bundles were made for super_scanner-0.0.2-py3-none-any.whl:
Publisher:
workflow.yml on KarAshutosh/super-scanner
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
super_scanner-0.0.2-py3-none-any.whl -
Subject digest:
ddf9e999a86e459bf4ceab5d7c2e67404015061eeea5eaa27b8db19600c6292b - Sigstore transparency entry: 2118486108
- Sigstore integration time:
-
Permalink:
KarAshutosh/super-scanner@f4f33c3cce1aab9e3c05db8fe54e539ebbb74dec -
Branch / Tag:
refs/heads/main - Owner: https://github.com/KarAshutosh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@f4f33c3cce1aab9e3c05db8fe54e539ebbb74dec -
Trigger Event:
workflow_dispatch
-
Statement type: