Skip to main content

Open-source iterative threat modeling powered by LLMs - STRIDE + MAESTRO frameworks with DREAD scoring

Project description

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 to run: docker compose up [Coming Soon]
  • Multi-Provider LLM: Anthropic, OpenAI, or Ollama (fully local/air-gapped)
  • Dual Framework Support: STRIDE (traditional) + MAESTRO (AI/ML) auto-detected or run in parallel
  • DREAD Risk Scoring: Automatic risk assessment with 5 dimensions (0-10 scale each, averaged) for severity classification
  • Structured Input Templates: Tagged templates for component descriptions with assumption enforcement in the prompts
  • Iterative Refinement: 1–15 configurable iteration passes with gap analysis
  • Code-as-Input: Semantic code extraction via context-link MCP — --code /path/to/repo grounds threats in actual implementation
  • Image-as-Input: Architecture diagram support via --diagram arch.png (vision API) or --diagram flow.mmd (Mermaid text)
  • Deterministic Rule Engine: 362 curated patterns (STRIDE, MAESTRO, OWASP, MITRE ATT&CK, ATLAS, CAPEC, cloud misconfigurations) across 16 seed files — run alongside the LLM and merged into the final output
  • Persistent Results: Every run is saved to SQLite automatically — inspect past models with paranoid models list / paranoid models show
  • Export Formats: JSON (simple/full), SARIF (GitHub Security integration), Markdown (PRs / Confluence / Notion), PDF (security review sign-off)
  • Post-Run Export: Re-export any saved model in any format with paranoid models export — run once, export many times
  • Model Management: paranoid models delete removes a saved model and all its data; paranoid models prune bulk-deletes by age or status
  • Pre-flight Gap Analysis: Description completeness check before running — warns about missing auth, trust boundaries, data flows, and external integrations; --strict exits CI with code 2 on error-severity gaps
  • Edit Context Before Threats: Review and edit extracted assets, flows, and trust boundaries at /models/:id/context before or after a run; "Re-extract" re-runs only the extraction steps without regenerating threats
  • DREAD Score Editing: Edit any threat's DREAD scores inline from the Review page — no page reload required
  • Fast Provider Routing: Configurable FAST_MODEL uses a Haiku-class model for extraction and enrichment, reserving Sonnet/Opus for threat generation — cuts API cost without sacrificing quality
  • Attack Tree & Test Case Enrichment: --enrich generates STRIDE/MAESTRO attack trees and Gherkin test cases per threat after the main pipeline run; included automatically in Markdown and PDF exports
  • Editable Settings (Web UI): Runtime configuration editing at /settings — change provider, model, iterations, and more without restarting; protected by optional CONFIG_SECRET shared secret
  • CI/CD Ready: CLI + GitHub Action with SARIF upload for automated threat detection

Quick Start

Step 1: Install

Choose the method that works best for you:

PyPI (Recommended):

pip install paranoid-cli
paranoid --version

Docker (self-hosted, web UI + CLI):

git clone https://github.com/theAstiv/paranoid && cd paranoid

# Configure your LLM provider
cp .env.example .env
# Edit .env — at minimum set ANTHROPIC_API_KEY (or OPENAI_API_KEY)

# Build and start (first build: ~5-10 min for Go + Node + Python stages)
docker compose up --build

# Web UI
open http://localhost:8000/app

# API docs (OpenAPI)
open http://localhost:8000/docs

See Running with Docker for build args, offline builds, and CLI usage inside the container.

Standalone Binary (No Python Required):

Download the pre-built binary for your platform from GitHub Releases:

Platform Binary
Linux x86_64 paranoid-linux-x64
macOS ARM64 (Apple Silicon) paranoid-macos-arm64
Windows x64 paranoid-windows-x64.exe
# Linux/macOS
chmod +x paranoid-linux-x64
./paranoid-linux-x64 --help

From Source (Development):

git clone https://github.com/theAstiv/paranoid
cd paranoid
pip install -e .

Step 2: Configure

Option A: Interactive Wizard (Recommended)

paranoid config init

# Follow prompts to configure:
#   - LLM Provider (Anthropic/OpenAI/Ollama)
#   - API Key
#   - Model name
#   - Default iterations

paranoid config show

Option B: Environment Variables

cp .env.example .env

Edit .env and add your provider configuration:

# Anthropic (Recommended)
ANTHROPIC_API_KEY=sk-ant-api03-xxxxxxxxx
DEFAULT_PROVIDER=anthropic
DEFAULT_MODEL=claude-sonnet-4-20250514

# OR OpenAI
OPENAI_API_KEY=sk-xxxxxxxxx
DEFAULT_PROVIDER=openai
DEFAULT_MODEL=gpt-4o

# OR Ollama (fully local, no API key)
OLLAMA_BASE_URL=http://localhost:11434
DEFAULT_PROVIDER=ollama
DEFAULT_MODEL=llama3

# Optional: path to context-link binary for --code flag
# If unset, Paranoid looks for bin/context-link then PATH
CONTEXT_LINK_BINARY=/usr/local/bin/context-link

# Optional: fast model for extraction/enrichment steps (Anthropic only)
# Defaults to claude-haiku-4-5-20251001; set to same value as DEFAULT_MODEL to disable fast routing
FAST_MODEL=claude-haiku-4-5-20251001

# Optional: shared secret to protect PATCH /config (web UI settings page)
# If set, the Settings page requires this value to save any configuration change
CONFIG_SECRET=your-secret-here

# Optional: restrict CORS origins (default: * allows all)
# Comma-separated for multiple origins
CORS_ORIGINS=https://app.example.com,https://staging.example.com

Step 3: Run Your First Threat Model

# Run with an example
paranoid run examples/stride-example-api-gateway.md

# With architecture diagram (Mermaid, PNG, or JPG)
paranoid run examples/stride-example-api-gateway.md \
  --diagram examples/stride-api-gateway-architecture.mmd

# With your own system description
paranoid run my-system.md

# See all options
paranoid run --help

Expected Output:

Configuration:
  Provider: anthropic
  Model: claude-sonnet-4-20250514
  Iterations: 3
  Framework: STRIDE

[>] summarize: Generating system summary...
[OK] summarize: Summary generated: 196 chars
[>] extract_assets: Identifying assets and entities...
[OK] extract_assets: Identified 14 assets/entities
[>] extract_flows: Extracting data flows and trust boundaries...
[OK] extract_flows: Identified 12 flows, 6 boundaries
[>] generate_threats [iter 1]: Generating threats (iteration 1/3)...
[OK] generate_threats [iter 1]: Generated 10 threats
...
[OK] complete: Pipeline complete: 2 iterations, 17 threats

================================================================================
THREAT MODEL COMPLETE
================================================================================
Total Threats:      17
Iterations:         2
Duration:           115.0 seconds
Output:             stride-example-api-gateway_threats.json

Expected Runtime:

  • Claude Sonnet: ~30-60 seconds (3 iterations)
  • GPT-4: ~45-90 seconds (3 iterations)
  • Ollama (local): 2-5 minutes (depends on hardware)

CLI Reference

Running Threat Models

# Basic usage (auto-detects framework from input)
paranoid run system.md

# Structured templates (auto-detects STRIDE vs MAESTRO)
paranoid run examples/stride-example-api-gateway.md
paranoid run examples/maestro-example-rag-chatbot.md

# JSON output (simple format - lightweight, ~2-3 KB)
paranoid run system.md --output threats.json

# JSON output (full format - complete models + DREAD + events, ~45 KB)
paranoid run system.md --format full -o complete.json

# SARIF export for GitHub Security integration
paranoid run system.md --format sarif -o threats.sarif

# Markdown export for PRs, Confluence, and Notion
paranoid run system.md --format markdown -o threats.md

# Markdown export with auto-suffix (no extension needed)
paranoid run system.md --format markdown -o threats

# PDF export for security review sign-off and archival
paranoid run system.md --format pdf -o report.pdf

# PDF export with auto-suffix
paranoid run system.md --format pdf -o report

# Force dual framework (STRIDE + MAESTRO in parallel)
paranoid run system.md --maestro

# Override iteration count (1-15)
paranoid run system.md --iterations 7

# Override framework auto-detection
paranoid run system.md --framework MAESTRO

# Override provider and model for a single run (without changing config)
paranoid run system.md --provider openai --model gpt-4o
paranoid run system.md --provider anthropic --model claude-opus-4-5

# Quiet mode (suppress real-time output, show only summary)
paranoid run system.md --quiet

# Verbose mode (show detailed event data with complete models)
paranoid run system.md --verbose

# Code-as-input: ground threats in actual source code (requires context-link binary)
paranoid run system.md --code /path/to/repo

# Image-as-input: include architecture diagram (PNG/JPG via vision API)
paranoid run system.md --diagram architecture.png

# Image-as-input: Mermaid diagram as text (all providers)
paranoid run system.md --diagram flow.mmd

# Combined: description + diagram + code context
paranoid run system.md --diagram arch.png --code /path/to/repo

# Strict mode: exit code 2 if description has error-severity gaps (for CI gates)
paranoid run system.md --strict

# Gap warnings are always printed to stderr; --strict makes errors blocking
paranoid run system.md --strict --format sarif -o findings.sarif

# Generate attack trees + Gherkin test cases per threat after the pipeline run
# Requires Anthropic provider; uses FAST_MODEL (claude-haiku-4-5-20251001) if configured
paranoid run system.md --enrich

# Enrich and export to Markdown (attack trees + test cases included in output)
paranoid run system.md --enrich --format markdown -o enriched-report.md

# Enrich and export to PDF
paranoid run system.md --enrich --format pdf -o enriched-report.pdf

Inspecting Saved Models

Every paranoid run saves its results to SQLite automatically. Use the models subcommand to browse and inspect past runs without re-running the pipeline.

# List recent threat models (most recent first)
paranoid models list

# Limit results
paranoid models list --limit 50

# Machine-readable JSON output
paranoid models list --json

# Show threats for a saved model — partial ID works (first 8 chars)
paranoid models show a1b2c3d4

# Full UUID also accepted
paranoid models show a1b2c3d4-e5f6-7890-abcd-ef1234567890

# Show threats without mitigations
paranoid models show a1b2c3d4 --no-mitigations

# JSON output (model metadata + threats array)
paranoid models show a1b2c3d4 --json

# Export a saved model to Markdown (run once, export many times)
paranoid models export a1b2c3d4 --format markdown -o report.md

# Export to PDF for security review sign-off
paranoid models export a1b2c3d4 --format pdf -o report.pdf

# Export to SARIF for GitHub Security
paranoid models export a1b2c3d4 --format sarif -o findings.sarif

# Export to JSON (simple summary or full raw dump)
paranoid models export a1b2c3d4 --format simple -o threats.json
paranoid models export a1b2c3d4 --format full -o complete.json

# Default output path (no -o flag): {id_prefix}_{format}.{ext} in cwd
paranoid models export a1b2c3d4 --format markdown

# Delete a saved model and all its data (prompts for confirmation)
paranoid models delete a1b2c3d4

# Delete without prompt (for scripting/CI)
paranoid models delete a1b2c3d4 --yes

# Prune old models (older than 30 days)
paranoid models prune --older-than 30

# Prune all failed models without prompting
paranoid models prune --status failed --yes

# Combine filters: old AND failed
paranoid models prune --older-than 7 --status failed

Example models list output:

  ID          Title                 Framework  Threats  Status      Date
  --------------------------------------------------------------------------
  a1b2c3d4    api-gateway           STRIDE           23  completed   2026-04-01 14:32
  e5f6g7h8    auth-service          STRIDE           17  completed   2026-03-28 09:15
  c9d0e1f2    rag-chatbot           MAESTRO          31  completed   2026-03-25 11:04

Example models show output:

  Threat Model: api-gateway
  ============================================================
  ID:           a1b2c3d4-...
  Framework:    STRIDE
  Threats:      23
  Iterations:   3

  THREATS
  ------------------------------------------------------------
  [1] SQL Injection  (Tampering)  pending
      Target: PostgreSQL DB  |  Impact: High  |  Likelihood: Medium
      → Use parameterized queries
      → Apply input validation
  ...

Configuration Management

# Interactive setup wizard
paranoid config init

# Reconfigure (overwrite existing config)
paranoid config init --force

# Display current configuration
paranoid config show

# Config file location: ~/.paranoid/config.json

Version Info

# Show version, Python version, dependencies, and current configuration
paranoid version

Running with Docker

The Docker image bundles all three components — FastAPI backend, Svelte frontend, and the context-link MCP binary — into a single container. The frontend is served as static files from FastAPI at /app.

Standard build

git clone https://github.com/theAstiv/paranoid && cd paranoid
cp .env.example .env           # copy and edit with your API key
docker compose up --build      # builds all three stages, then starts the server

First build takes roughly 5–10 minutes (Go toolchain download + Node modules + Python dependencies + fastembed model pre-bake). Subsequent builds are fast due to Docker layer caching.

Open the web UI: http://localhost:8000/app
Open the API docs: http://localhost:8000/docs

Configuration

Set environment variables in .env (picked up automatically by docker compose):

# Minimum — set at least one provider key
ANTHROPIC_API_KEY=sk-ant-api03-xxx
DEFAULT_PROVIDER=anthropic
DEFAULT_MODEL=claude-sonnet-4-20250514

# Optional overrides (defaults shown)
DEFAULT_ITERATIONS=3
PORT=8000
LOG_LEVEL=info
CORS_ORIGINS=*
SIMILARITY_THRESHOLD=0.85

# Fast model for extraction/enrichment (Anthropic only, optional)
FAST_MODEL=claude-haiku-4-5-20251001

# Shared secret to protect the Settings PATCH /config endpoint (optional)
CONFIG_SECRET=your-secret-here

All variables are documented in .env.example.

Build arguments

Argument Default Purpose
CONTEXT_LINK_VERSION 1.0.0 context-link release to download from GitHub releases
EMBEDDING_MODEL BAAI/bge-small-en-v1.5 fastembed model to pre-bake into the image
# Pin to a specific context-link release
CONTEXT_LINK_VERSION=1.0.0 docker compose build

# Build with a different embedding model
EMBEDDING_MODEL=BAAI/bge-base-en-v1.5 docker compose build

Building without context-link (offline / no Go toolchain)

If you can't reach GitHub at build time, remove the Go stage:

  1. Comment out or delete the context-link-builder stage in Dockerfile.
  2. Remove the COPY --from=context-link-builder line in the final stage.
  3. Mount your own pre-built binary at runtime:
# docker-compose.yml — uncomment this volume entry
volumes:
  - ./data:/app/data
  - /path/to/context-link:/app/bin/context-link:ro

The app works without the binary — the --code flag just logs a warning and runs without code context.

Using the CLI inside the container

# Run a threat model against a file already inside the container
docker compose exec app paranoid run /app/examples/stride-example-api-gateway.md

# Mount a local file and run it
docker run --rm \
  -v $(pwd)/my-system.md:/workspace/system.md \
  -v $(pwd)/data:/app/data \
  -e ANTHROPIC_API_KEY=sk-ant-xxx \
  paranoid-app-1 \
  paranoid run /workspace/system.md --format markdown -o /app/data/out.md

Persistent data

The SQLite database is stored at /app/data/paranoid.db inside the container, bind-mounted to ./data/ on the host. This directory persists threat models across container restarts and image upgrades.


Output Formats

JSON Simple (default, ~2-3 KB)

Lightweight threat summaries for CI/CD dashboards and quick reviews.

{
  "execution": {
    "total_threats": 17,
    "iterations_completed": 2,
    "duration_seconds": 115.0
  },
  "threats": [
    {
      "name": "JWT Token Forgery",
      "category": "Spoofing",
      "target": "API Gateway",
      "impact": "Complete authentication bypass",
      "likelihood": "Medium",
      "mitigation_count": 3
    }
  ]
}

JSON Full (~45 KB)

Complete Pydantic models with DREAD scores and full pipeline event audit trail. Suitable for detailed analysis, archival, and integration with other tools.

paranoid run system.md --format full -o complete.json

Markdown (~4–15 KB)

Human-readable reports for PRs, Confluence, Notion, and security review documents. Contains a summary table, per-category threat sections, DREAD scores, and tagged mitigations.

paranoid run system.md --format markdown -o threats.md

Output structure:

# Threat Model: my-system

**Framework:** STRIDE | **Model ID:** `a1b2c3d4` | **Generated:** 2026-04-02

## Summary
| # | Threat | Category | Target | Likelihood | DREAD |
...

## Threats

### Tampering

#### 1. SQL Injection
**Target:** Database | **Likelihood:** High | **Impact:** Data breach
**DREAD:** 7.5/10 *(D:8 R:7 E:8 A:6 Di:7)*

> An attacker exploits unparameterized queries...

**Mitigations:**
- [P] Use parameterized queries / prepared statements
- [D] Enable query anomaly logging

Pass include_header=False when calling export_markdown() directly to omit the H1 heading and metadata block for embedding into existing documents.

PDF (~50–200 KB)

Structured PDF reports for security review sign-off, archival, and sharing with stakeholders who don't use Markdown. Contains the same content as the Markdown export: title, metadata, summary table, per-category threat sections, DREAD scores, and tagged mitigations. Produced via reportlab — no external binaries required.

paranoid run system.md --format pdf -o report.pdf
paranoid models export a1b2c3d4 --format pdf -o report.pdf

SARIF (GitHub Security Integration)

SARIF 2.1.0 format for GitHub Security tab, GitLab, VS Code, and Azure DevOps:

paranoid run system.md --format sarif -o threats.sarif

GitHub Actions Integration:

Use the official Paranoid action for zero-config SARIF upload to the GitHub Security tab:

name: Threat Model

on: [push, pull_request]

permissions:
  security-events: write
  contents: read

jobs:
  threat-model:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Paranoid threat modeling
        id: paranoid
        uses: theAstiv/paranoid@v1.4.0
        with:
          description-file: docs/system-description.md
          provider: anthropic
          api-key: ${{ secrets.ANTHROPIC_API_KEY }}
          framework: STRIDE
          iterations: 3

      - name: Upload SARIF to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: ${{ steps.paranoid.outputs.sarif-file }}

Action inputs:

Input Default Description
description-file Path to system description (.md / .txt), relative to repo root
provider anthropic anthropic, openai, or ollama
api-key Provider API key; omit for Ollama
model provider default Model override (e.g. claude-sonnet-4-5, gpt-4o)
framework STRIDE STRIDE or MAESTRO
iterations 3 Pipeline iterations (1–15)
sarif-output paranoid-results.sarif SARIF output path
strict false Exit 2 on error-severity description gaps
fail-on-findings false Fail the step if any threats are found

Code-as-Input (--code)

Ground threats in actual source code using the context-link MCP binary. When --code is provided, Paranoid extracts a semantically relevant slice of the codebase and threads it through every pipeline node.

paranoid run system.md --code /path/to/repo
paranoid run system.md --code /path/to/repo --iterations 5
paranoid run system.md --diagram arch.png --code /path/to/repo  # combined

How it works:

  1. Three-tier extraction funnel (50KB budget, ~12.5K tokens):

    • Semantic search: semantic_search_symbols finds symbols relevant to the threat model description
    • Code body extraction: get_code_by_symbol fetches full source for top results
    • File skeletons: get_file_skeleton fills remaining budget with structural outlines
  2. Code summary step: _deterministic_code_summary() extracts a focused ~2KB CodeSummary (tech stack, entry points, auth patterns, data stores, security observations) from CodeContext using file-extension mapping, import scanning, and keyword matching — no LLM call required. summarize_code() (LLM-backed) is available as an opt-in upgrade path when pattern matching isn't sufficient.

  3. Full pipeline threading: The CodeSummary is passed to all downstream nodes — extract_assets, extract_flows, generate_threats, and gap_analysis — so threats reference actual implementation details.

  4. Deterministic extraction: _deterministic_code_summary() covers tech stack from file extensions, HTTP routes from decorator patterns, auth/DB/HTTP-client keywords, and security anti-patterns (eval(), pickle.load, shell=True, SQL string concatenation). The pipeline never silently drops code context.

Installing context-link:

context-link is a standalone Go binary that indexes your repository and serves an MCP tool interface over stdio. Get it from github.com/context-link-mcp/context-link:

# Option 1: pre-built binary (recommended — no Go toolchain required)
# Download the binary for your platform from the GitHub Releases page:
# https://github.com/context-link-mcp/context-link/releases/latest
# Then place it at bin/context-link or add it to PATH.

# Option 2: build from source (requires Go 1.22+)
git clone https://github.com/context-link-mcp/context-link
cd context-link
CGO_ENABLED=1 go build -o context-link ./cmd/context-link
# Move the resulting binary to bin/context-link or PATH

Requirements:

  • context-link binary at bin/context-link (relative to working directory), on PATH, or at the path set by CONTEXT_LINK_BINARY
  • Binary discovery order: explicit CONTEXT_LINK_BINARY env var → ./bin/context-linkshutil.which("context-link")
  • If the binary is not found, Paranoid logs a warning and continues without code context

Error handling: Every MCP failure degrades gracefully — binary not found, subprocess crash, tool call error, and index timeout all produce a warning and allow the pipeline to continue with text-only input.


Code Sources (Web UI)

The web UI lets you clone and index Git repositories directly from the browser, then select a source when creating a new threat model — no CLI or Docker volume required.

Adding a code source

  1. Navigate to Sources in the top navigation.
  2. Click Add source and fill in:
    • Git URLhttps://github.com/owner/repo.git (GitHub, GitLab, Bitbucket, or hosts added via ADDITIONAL_GIT_HOSTS)
    • Name — a short label shown in the wizard
    • Branch / tag / commit (optional) — leave blank to track the default branch; enter a commit SHA to pin to a specific revision
    • Personal access token (optional) — for private repos; stored Fernet-encrypted at rest
  3. Click Add & clone. The source card shows live progress: queued → cloning → indexing → ready.

Once a source is ready, select it in the Code Source step of the New Model wizard. The pipeline extracts a semantically relevant slice of the codebase and threads it through every threat-generation step.

Security model for stored credentials

  • PATs are Fernet-encrypted (AES-128-CBC + HMAC-SHA256) before being written to SQLite.
  • Key derivation: CONFIG_SECRET env var → PBKDF2-HMAC-SHA256 (100k iterations); falls back to a random 32-byte file key at data/.source_key (mode 0600).
  • The raw PAT is never logged, never included in SSE events, and never returned by any API endpoint (has_pat: bool only).
  • Git clones use hardened flags: protocol.file.allow=never (blocks submodule file:// transport), core.symlinks=false, GIT_TERMINAL_PROMPT=0.

Requirements

  • RAM: 4 GB minimum. The fastembed ONNX embedding model (~130 MB resident), context-link indexer, and a git clone of a large monorepo can peak at 2–3 GB together; leave headroom for the LLM pipeline.
  • Disk: clone directories live at data/sources/<id>/ inside the mounted data volume.
  • Network: HTTPS-only git URLs; host allowlist is github.com, gitlab.com, bitbucket.org by default.
# Allow additional private hosts (exact hostname match, no wildcards)
ADDITIONAL_GIT_HOSTS=git.company.com,git.internal.net docker compose up

Image-as-Input (--diagram)

Supply an architecture diagram alongside your text description. Paranoid passes it to every pipeline node for richer threat coverage.

# PNG or JPG via vision API
paranoid run system.md --diagram architecture.png
paranoid run system.md --diagram architecture.jpg

# Mermaid (.mmd) as text — works with all providers
paranoid run system.md --diagram flow.mmd

# Combined with code context
paranoid run system.md --diagram arch.png --code /path/to/repo

Supported formats:

Format Mechanism Size Limit
PNG Vision content block (base64) 5MB
JPG/JPEG Vision content block (base64) 5MB
Mermaid .mmd <architecture_diagram> XML tag (text) 100KB

Provider support:

Provider PNG/JPG Mermaid
Anthropic (all models) Full support Full support
OpenAI gpt-4o, gpt-4o-mini Full support Full support
OpenAI other models Not supported (use gpt-4o) Full support
Ollama Logs warning, continues without image Full support

How it works:

  • PNG/JPG: The image is base64-encoded and passed as a vision content block in the provider's native format (Anthropic image content block; OpenAI image_url data URI). Each prompt's <architecture_diagram> instruction is replaced with a vision-specific directive.
  • Mermaid: The .mmd file is read as UTF-8 text and injected as <architecture_diagram> XML in the prompt. All providers parse Mermaid syntax natively — no rendering required.
  • Pipeline threading: DiagramData threads through all 5 pipeline nodes: summarize, extract_assets, extract_flows, generate_threats, and gap_analysis.

Structured Input Templates

Paranoid supports rich XML-tagged templates for better context and assumption enforcement. See Input-template.md for the full template reference and examples/ for working examples.

STRIDE Template (traditional systems): Component description with technology stack, interfaces, data handling, and 6 structured assumption sections.

MAESTRO Template (AI/ML systems): Extended component description with mission alignment, agent profile, and 9 structured assumption sections.

Model Configuration

Use Claude Sonnet (or newer) for reliable structured output generation.

Model Status Notes
claude-sonnet-4-20250514 Recommended Validated end-to-end, reliable for production
claude-haiku-4-5-20251001 Not recommended as main model Fails with JSON parsing errors on complex threat outputs; recommended as FAST_MODEL for extraction/enrichment steps
gpt-4o Supported Works well, also supports vision (--diagram)
Ollama (Llama 3 70B+) Supported Fully local, no external API calls

Architecture

  • Backend: FastAPI + SQLite + sqlite-vec (loaded via sqlite_vec.loadable_path() — works on Windows without manual DLL installation)
  • Frontend: Svelte + Tailwind SPA with svelte-spa-router — implemented (see frontend/); available when running the web server (uvicorn backend.main:app)
  • LLM Providers: Anthropic / OpenAI / Ollama (protocol-based, swappable)
  • Pipeline: Plain async functions (no LangChain, no LangGraph)
  • Embeddings: Local via fastembed (ONNX, BAAI/bge-small-en-v1.5)
  • Models: Pydantic v2 for all data validation
  • Frameworks: STRIDE (traditional) + MAESTRO (AI/ML security)
  • Code context: context-link MCP binary (Go) + MCPCodeExtractor async context manager
  • Image input: backend/image/ package — encoder.py (PNG/JPG base64), mermaid.py (text load), validation.py (size/format)

Python API:

from backend.pipeline.runner import run_pipeline_for_model
from backend.providers.anthropic import AnthropicProvider
from backend.models.enums import Framework

provider = AnthropicProvider(model="claude-sonnet-4-20250514", api_key="your-key")

async for event in run_pipeline_for_model(
    model_id="web-app-001",
    description="E-commerce web application...",
    framework=Framework.STRIDE,
    provider=provider,
    max_iterations=3,
):
    print(f"[{event.step}] {event.message}")

Testing

# Run unit/integration tests (no API key required)
pytest tests/ -v

# Run end-to-end pipeline test (requires ANTHROPIC_API_KEY)
pytest tests/test_pipeline_e2e.py -v

# Validate structured input parser (no API key required)
python examples/test_structured_input.py

# Lint
ruff check backend/ cli/
ruff format backend/ cli/

Troubleshooting

Authentication errors:

  • Check your API key is correct in .env or ~/.paranoid/config.json
  • For Anthropic, ensure billing is set up and key starts with sk-ant-api03-

Module not found:

pip install -e .  # or: pip install paranoid-cli

Ollama connection refused:

ollama serve  # start Ollama first, then run paranoid

--code flag: context-link binary not found:

Install context-link from github.com/context-link-mcp/context-link (pre-built binaries on the Releases page), then make it available to Paranoid:

# Option 1: set env var pointing to the binary
export CONTEXT_LINK_BINARY=/path/to/context-link

# Option 2: place binary at bin/context-link relative to working directory

# Option 3: add context-link to PATH

If the binary is missing, Paranoid logs a warning and continues without code context.

sqlite-vec not loading (Windows "module not found"):

This was a known issue on Windows where a bare vec0 extension name was used. It is fixed in the current release — the extension is now loaded via the absolute path from the bundled sqlite-vec Python package (sqlite_vec.loadable_path()), which resolves correctly on all platforms. No manual DLL installation required; pip install paranoid-cli includes everything.

--diagram with OpenAI and vision errors: Only gpt-4o and gpt-4o-mini support JSON structured output together with vision. Other OpenAI models that support vision do not support JSON mode simultaneously. Switch to gpt-4o or use Anthropic.

--diagram with Ollama: Ollama does not support vision for most models. Paranoid logs a warning and continues without the image. Use --diagram flow.mmd (Mermaid text) instead — all providers support Mermaid.

macOS binary "developer cannot be verified":

xattr -d com.apple.quarantine paranoid-macos-arm64

Windows "Windows protected your PC": Click "More info" then "Run anyway", or add an exception in Windows Defender.

Platform Support

Platform PyPI Docker Binary
Ubuntu 20.04+ Yes Yes Yes
Debian 11+ Yes Yes Yes
RHEL 8+ Yes Yes Yes
macOS 11+ (Intel) Yes Yes No
macOS 11+ (ARM64) Yes Yes Yes
Windows 10+ Yes Yes Yes
WSL2 Yes Yes Yes

Documentation

Developer docs:

Development Status

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

Completed: Core pipeline (8 nodes, iteration logic, SSE, dual framework), LLM providers (Anthropic/OpenAI/Ollama), STRIDE + MAESTRO prompts, structured input templates, JSON + SARIF + Markdown + PDF export, DREAD scoring, CLI with config wizard, code-as-input via context-link MCP (--code CLI and code sources web UI), image-as-input via vision API and Mermaid text (--diagram), deterministic rule engine (362 curated patterns across 16 seed files, RAG retrieval), provider offline fallback (rule-engine-only mode), Anthropic prompt caching (~20–30% token reduction), full SQLite persistence (every run saved with assets/flows/threats/DREAD), full CRUD for all 12 schema entities, paranoid models list/show/export/delete/prune commands, --provider/--model run-time overrides, REST API (26+ routes with SSE and full CRUD), Svelte + Tailwind frontend (all pages and components implemented), Docker Compose deployment (3-stage build: Go + Node + Python, web UI served at /app), packaging and release automation, fast provider routing (FAST_MODEL for extraction/enrichment), --enrich CLI flag (attack trees + Gherkin test cases per threat), enrichment included in Markdown/PDF exports, encrypted API key + PAT storage (Fernet), first-run redirect + Settings UI overhaul, provider liveness probe, git clone + index pipeline with SSE progress, CSRF protection (ALLOWED_ORIGINS).

Future (v2.0+): Multi-user collaboration.

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

paranoid_cli-1.5.0.tar.gz (302.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

paranoid_cli-1.5.0-py3-none-any.whl (298.0 kB view details)

Uploaded Python 3

File details

Details for the file paranoid_cli-1.5.0.tar.gz.

File metadata

  • Download URL: paranoid_cli-1.5.0.tar.gz
  • Upload date:
  • Size: 302.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for paranoid_cli-1.5.0.tar.gz
Algorithm Hash digest
SHA256 6ca9b7b3a7063b50242b39290d8a453fa7521ac5556ae8720296b1809233d7a2
MD5 7862f2cf1b34948073d6070c0ad2be43
BLAKE2b-256 bdfda777e00a1ca5cc357e7f1b9241259335b11740040ae9b7bd7613f32d393f

See more details on using hashes here.

Provenance

The following attestation bundles were made for paranoid_cli-1.5.0.tar.gz:

Publisher: release.yml on theAstiv/paranoid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file paranoid_cli-1.5.0-py3-none-any.whl.

File metadata

  • Download URL: paranoid_cli-1.5.0-py3-none-any.whl
  • Upload date:
  • Size: 298.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for paranoid_cli-1.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f5893f8c6269030bde5c94db913d0842e0551f7080f4ab83b4717039b9192d47
MD5 6fe291115876ab3eb324dc319ef4e8f8
BLAKE2b-256 ebe73f0635aafe9bc4ef6dae16acebb7f479d51c7fbc7a683f3c3f784b664931

See more details on using hashes here.

Provenance

The following attestation bundles were made for paranoid_cli-1.5.0-py3-none-any.whl:

Publisher: release.yml on theAstiv/paranoid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page