Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Paranoid: threat modeling that iterates, with receipts. Self-hosted STRIDE + MAESTRO threat models with a deterministic fallback and a dependency capability engine for npm.

Paranoid

Open-source, self-hosted, iterative threat modeling powered by LLMs.

Paranoid takes system descriptions (text, diagrams, or code via MCP) and produces comprehensive STRIDE + MAESTRO threat models through an LLM-powered pipeline with deterministic fallback. Configure 1–15 automated iteration passes, then review threats in a human-in-the-loop approve/reject cycle.

Features

  • Zero Infrastructure: SQLite + sqlite-vec. One command: docker compose up
  • Multi-Provider LLM: Anthropic, OpenAI, Ollama (fully local/air-gapped), or AWS Bedrock
  • Dependency Capability Engine: static-analysis visibility into what an npm dependency can do (network, filesystem, process, dynamic code, native addons), diffed against its own GitHub source — see below
  • Dual Framework: STRIDE (traditional) + MAESTRO (AI/ML) — auto-detected or run in parallel
  • DREAD + CVSS Risk Scoring: automatic 5-dimension DREAD (0–10) and/or a standalone CVSS v3.1 base-score calculator, selectable per run
  • ATT&CK / ATLAS Enrichment: every threat — LLM-generated, rule-engine, or dependency — is mapped to MITRE ATT&CK/ATLAS techniques (deterministic rule table, pattern-ID regex, or embedding similarity depending on origin), never self-attributed by the LLM
  • Iterative Refinement: 1–15 configurable iteration passes with gap analysis
  • Pre-flight Gap Check: before a run, the wizard flags missing authentication, trust-boundary, data-flow and external-system details in the description and assumptions; deterministic checks first, then an optional LLM pass, with a strict mode that blocks the run on error-severity gaps
  • Editable Context: add, edit or delete assets, flows and trust boundaries on the Results page; edits relink threats and appear in exports. A Re-run or Re-extract replaces them with fresh extraction (keeping them is on the roadmap); to fix the context a CLI run uses, pass --seeded-assets / --seeded-flows
  • Model Diff: compare two models by embedding similarity (new / removed / unchanged threats)
  • Model Routing: per-pipeline-step fast/main model selection (e.g. Haiku for extraction, Sonnet for threat generation); the routed extraction steps cost about two-thirds less (measured), and the steps that write the threat text never leave the main model
  • Code-as-Input: Semantic code extraction via context-link MCP (--code /path/to/repo)
  • Image-as-Input: Multiple architecture diagrams per run — up to 5 named views (deployment, data flow, etc.) via a repeatable -d on the CLI (-d arch.png -d flow.mmd) or the API's diagrams[] field, rendered with a proper ELK layout
  • Deterministic Rule Engine: 362 curated patterns (STRIDE, MAESTRO, OWASP, MITRE ATT&CK/ATLAS, CAPEC, cloud misconfigs) across 16 seed files
  • Export Formats: JSON, SARIF (GitHub Security), Markdown, PDF
  • Multi-User Collaboration: Projects with owner/editor/viewer RBAC, threaded comments, assignments, activity log
  • CI/CD Ready: CLI + GitHub Action with SARIF upload

Quick Start

# Install
pip install paranoid-cli

# Configure
paranoid config init

# Run (the examples are in the repo, not the package: clone it, or fetch one)
curl -fsSLO https://raw.githubusercontent.com/theAstiv/paranoid/main/examples/stride-example-api-gateway.md
paranoid run stride-example-api-gateway.md   # saved to the database; add -o threats.json for a file

Docker (web UI + API):

git clone https://github.com/theAstiv/paranoid && cd paranoid
cp .env.example .env        # add your API key
mkdir -p data               # must be writable by uid 1000: `sudo chown 1000:1000 data` if yours differs
docker compose up --build   # web UI at http://localhost:8000/app

Note: the dependency capability engine, Bedrock, model routing, multiple diagrams, CVSS and ATT&CK/ATLAS mapping need v1.6.0 or later (pip install "paranoid-cli>=1.6.0"). The dependency engine also needs Semgrep on PATH (pip install semgrep); the Docker image includes it.

Try the full demo (Black Hat India Arsenal 2026)

examples/arsenal-deps/ is "MediaDrop", a fictional image-upload service with 8 real npm dependencies and three diagrams of the same system. Every command below runs against it.

# 1. Dependency capabilities inside a threat model (heatmap + drift in the web UI)
paranoid run examples/arsenal-deps/description.md \
  --manifest examples/arsenal-deps/package.json \
  --lockfile examples/arsenal-deps/package-lock.json --deps-source both

#    A reconstructed (inert) event-stream-style incident: capability delta + drift, no LLM call
python examples/arsenal-deps/inject_incident.py --source both --no-llm

# 2. Three diagrams, ATT&CK/ATLAS techniques, CVSS next to DREAD
paranoid run examples/arsenal-deps/description.md -n 2 \
  -d examples/arsenal-deps/diagrams/architecture.mmd \
  -d examples/arsenal-deps/diagrams/upload-flow.mmd \
  -d examples/arsenal-deps/diagrams/deployment.png \
  --step-model extract_assets=main --step-model extract_flows=main \
  --scoring-method both

# 3. Iterations + model routing, SARIF for GitHub code scanning
paranoid run examples/arsenal-deps/description.md -n 3 -v \
  --manifest examples/arsenal-deps/package.json \
  --lockfile examples/arsenal-deps/package-lock.json \
  --format sarif -o mediadrop.sarif

CLI runs are saved to the local database (paranoid models list); start the web UI against the same DB_PATH to open them at http://localhost:8000/app. Set ANTHROPIC_EFFORT=medium for Claude: at the default effort a run takes about three times as long. Measured costs, timings and their sample sizes are in Benchmarks.

What the dependency engine claims: capability visibility plus change and discrepancy triage: what a dependency can do, what changed in a release, and what ships in the npm tarball that isn't in the repo. It doesn't claim to catch supply-chain attacks; see what it does not catch.

Hand off to a coding agent

Export a model as the Markdown report and give it to Claude Code, Cursor or another coding agent as security requirements:

paranoid models export <model-id> --format markdown -o threats.md

This is the ordinary Markdown report, not an agent-specific format: assets, flows and trust boundaries, then each threat with its target, description, DREAD/CVSS score and mitigations. It includes every threat whatever its review status, so remove rejected ones from the file before handing it over. A dedicated format is on the roadmap.

Documentation

Guide Description
Getting Started Install, configure, and run your first threat model
CLI Reference All flags, subcommands, and output formats
Configuration All environment variables and config options
Web UI Guide Browser interface walkthrough
Authentication Multi-user setup, JWT, PATs, RBAC
API Reference REST API — 86 route handlers across 13 route modules, plus /health and / in main.py
GitHub Action Automated threat modeling in CI/CD
Architecture System design, pipeline, data model
Benchmarks An 11-model comparison on AWS Bedrock, routing savings per step, multi-diagram extraction, iterations, wall time, reliability and dependency-engine gates — dated, with sample sizes and caveats
Deployment Docker, PyPI, binary, production hardening

Other docs:

Dependency capability engine

Static-analysis visibility into what an npm dependency can actually do — network access, filesystem, process spawning, dynamic code, native addons, and more — compared against its declared GitHub source, so a version bump that quietly adds a capability shows up before you install it.

# What can this package do? Fetches npm tarball + GitHub source, runs Semgrep.
paranoid deps scan chalk@5.3.0 --source both

# Did capabilities change between two versions? (this is the *shape* of
# checks that would have caught the real ua-parser-js/event-stream
# supply-chain compromises: a patch release quietly adding a capability
# nothing in the diff would obviously explain. These two specific versions
# are both clean — the actual malicious 0.7.29 was unpublished — this just
# shows the delta computing cleanly against real registry data.)
paranoid deps diff ua-parser-js 0.7.28 0.7.30 --source both

# Sweep every direct dependency in your project's package.json
paranoid deps scan-manifest path/to/your-project/package.json

Requires Semgrep on PATH (pip install semgrep) — see SEMGREP_BINARY, DEPS_CACHE_DIR, DEPS_MAX_TARBALL_MB in Configuration. Source is always fetched read-only; nothing scanned is ever executed or installed.

What deps scan reports: a CapabilityProfile per source — categories (network, filesystem, process, dynamic_code, native_ffi, persistence, authentication, environment, crypto, deserialization, build_install), each backed by file:line evidence and a real source snippet, plus any postinstall/preinstall lifecycle hooks.

What drift signals mean: with --source both, paranoid deps scan compares the npm tarball against the package's own GitHub source for one version, per file. paranoid deps diff is a separate comparison — did this package's capabilities change between two releases — computed from two tarball scans; with --source both it additionally reports drift for the newer version alone, using the same per-file logic described here:

  • matched / explained_by_sourcemap / explained_by_build — the tarball file's capabilities are all accounted for by the corresponding GitHub file, a valid source map, or a declared build step. No signal.
  • relocated (weak, informational) — a capability new to that file but already present elsewhere in the package. Worth a look, not proof of anything.
  • signal (strong) — a capability novel to the entire GitHub-side scan. This is the actionable finding: shipped code does something the published source doesn't explain anywhere.
  • generated_unverifiable (informational) — a file declared by the package's own GitHub manifest (never the tarball's — the tarball is attacker-controlled, so trusting its self-declaration would let an attacker excuse any file just by listing it) that a non-npm build toolchain (e.g. esbuild's Go build, cargo build.rs) produces outside of npm run build. Can't be verified against source either way; never contributes a strong signal.
  • unverifiable — the tarball file's GitHub counterpart couldn't be fetched (a skipped symlink, an over-long path). Excused only against the package-wide GitHub category set, so a genuinely novel category still signals.
  • Added postinstall/preinstall hooks are graded separately: a non-allowlisted addition is a strong signal on its own (the ua-parser-js-shaped compromise, caught without needing a previous version to diff against).

What it does not catch:

  • Runtime-fetched payloads. A package that fetch()s and eval()s a remote payload at runtime shows up as a network/dynamic_code capability — the engine flags that the capability exists, not what the fetched code will do.
  • Obfuscation beyond the flagged shapes. The scanner recognizes specific, deliberate evasion patterns (aliased require/Function, concatenated or computed property calls, low-level process.binding, etc. — see backend/deps/rules/js/dynamic_code.yaml), not every possible way to hide a call. A sufficiently determined, hand-crafted obfuscation can still slip past static analysis; this is capability visibility and drift triage, not a guarantee of detection.
  • Generated files with no declared build step, or generated outside a recognized non-npm toolchain marker, still count as ordinary shipped code and can trip a signal even when they're legitimately build output.
  • Non-JS/TS package ecosystems. Layer 1 is npm/JS+TS only; PyPI and other ecosystems aren't covered yet.

Read this as "here's what changed and what looks unexplained," not "this dependency is safe" or "this dependency is malicious" — every signal is meant to be triaged by a person, not acted on automatically.

Supported platforms

Platform PyPI Docker Binary
Ubuntu 20.04+ ✓ ✓ ✓¹
macOS 11+ ARM64 ✓ ✓ ✓
Windows 10+ ✓ ✓ ✓
WSL2 ✓ ✓ ✓¹

¹ From v1.6.0 (paranoid-linux-x64). The v1.5.0 release has no Linux binary: its macOS build overwrote it, as both were named paranoid.

Full platform matrix: docs/deployment.md

Development Status

v1.6.0 — dependency capability engine, multi-user collaboration (accounts, projects, roles), AWS Bedrock, per-step model routing, multiple diagrams with ELK rendering, ATT&CK/ATLAS mapping and CVSS v3.1 scoring. See the CHANGELOG.

v1.5.0 — Non-technical users can open the web app, paste an API key, link a Git repo, and get a threat model — no terminal required.

Roadmap

  1. Real-malware recall: run the dependency engine on real malicious npm samples, handled as inert data, and publish k of N with the misses.
  2. Product-scope models: break a product into components, then combine their models, remove duplicates and flag contradictions between components.
  3. PyPI ecosystem: the same capability, drift and delta analysis for Python dependencies.
  4. Reachability v2: which dependency capabilities your own code can actually reach.

Also planned:

  • Re-run keeps your edits: Re-run and Re-extract reuse edited assets, flows and trust boundaries, and Re-run keeps the previous run so the two can be diffed automatically.
  • Design documents as input: PRDs, BRDs and PDFs alongside descriptions, diagrams and code.
  • Org knowledge base: upload internal standards or compliance docs for the pipeline to retrieve from.
  • Coding-agent export: threats written as security requirements and acceptance criteria.
  • OIDC/SSO federation.

License

Apache 2.0

Metadata

Release files for paranoid-cli 1.6.1rc1

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

Source distribution (sdist)

Source distribution for paranoid-cli 1.6.1rc1
File Size Uploaded Provenance Actions
paranoid_cli-1.6.1rc1.tar.gz 1.0 MB With provenance Details for paranoid_cli-1.6.1rc1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for paranoid-cli 1.6.1rc1
File Interpreter ABI Platform Actions
paranoid_cli-1.6.1rc1-py3-none-any.whl Python 3 none any Details for paranoid_cli-1.6.1rc1-py3-none-any.whl

Total release size: 2.1 MB

Release files / paranoid_cli-1.6.1rc1.tar.gz

Download URL paranoid_cli-1.6.1rc1.tar.gz
Size 1.0 MB
Tags Source
SHA-256 checksum
How to use checksums
7d16dd19a980c0a29ce8d66d8627ec0f269c400d0d19627ee63dbd0bc152aad9
BLAKE2b-256 checksum
How to use checksums
c44b14c1f672bf399163a8c5ac098eb96ac59dd6779cc7f59c63de68d82eef63
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 3, 2026.

Transparency log

Release files / paranoid_cli-1.6.1rc1-py3-none-any.whl

Download URL paranoid_cli-1.6.1rc1-py3-none-any.whl
Size 1.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
4dd8c07e133066767f78f036656d136abf8c2bff78e723a311869cac46985547
BLAKE2b-256 checksum
How to use checksums
ac2b8545a01a3703a7af5aec81058b9b4f4d4834bb6d911fd409ed401d856192
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 3, 2026.

Transparency log

Security for paranoid-cli 1.6.1rc1

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

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for paranoid_cli-1.6.1rc1.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 Nov 3, 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.

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