Reading the repo
Opening the box…
Reading the repo
Opening the box…
How to install on Windows
Ease and accurate way to generate diagrams and architecture from projects with a security focus
Saved setup from 4 h ago
Will it work on Windows?
CONTRIBUTING.mdThank you for your interest in contributing to secdiagram! We welcome contributions from developers, security researchers, and software architects of all backgrounds.
This guide outlines our development workflow, architectural principles, coding standards, and security policies to help you contribute effectively and safely.
Before writing code, please keep the four core tenets of secdiagram in mind:
dependencies = [] in pyproject.toml. This eliminates supply chain risk and ensures instant installation.diagram.mmd, graph.json, security.sarif, etc.). IDs are computed via deterministic hashing (stable_id). Never iterate over unordered sets or dict keys when writing outputs.secdiagram inspects untrusted repositories. It must never execute (eval, exec, importlib) analyzed code. All file reading, path resolutions, and YAML/JSON parses must be hardened against path traversal and deserialization attacks.We are committed to providing a friendly, safe, and welcoming environment for all contributors. Please treat others with respect, empathy, and professional courtesy in all project interactions, including issues, pull requests, and discussions.
@mermaid-js/mermaid-cli): For testing local offline PNG/SVG/PDF image rendering.Clone the repository:
git clone https://github.com/vserey/secdiagram.git
cd clone-secdiagram
Create and activate a virtual environment:
# Linux / macOS
python3 -m venv .venv
source .venv/bin/activate
# Windows (PowerShell)
python -m venv .venv
.venv\Scripts\Activate.ps1
Install the package in editable mode with development dependencies:
python -m pip install "pip==26.3"
pip install -e ".[dev]"
Development dependencies installed via .[dev] include:
ruff: High-speed linter and import formatter.mypy: Static type checker.coverage: Test coverage suite.bandit: Static application security testing (SAST) for Python.pip-audit: Known CVE dependency auditor.Run the full test suite using Python's built-in unittest runner:
# Run all unit tests
python -m unittest discover -s tests -v
# Run a specific test module
python -m unittest tests/test_security.py -v
# Run with test coverage
python -m coverage run -m unittest discover -s tests
python -m coverage report
Note: Test suite must achieve ≥ 80% coverage across
secdiagram_core. All existing 134+ tests must pass without regressions.
We use ruff for linting and import sorting:
# Check code style and imports
ruff check .
# Automatically apply safe fixes
ruff check . --fix
We use mypy with Python 3.10+ strict typing rules:
mypy
Run automated security gates before pushing commits:
# Run Bandit SAST gate (high severity)
python -m bandit -r secdiagram_core -lll
# Generate full Bandit JSON report
python -m bandit -r secdiagram_core -f json -o bandit.json
# Check installed dev dependencies for vulnerabilities
python -m pip_audit --strict --skip-editable
Every non-trivial change is tracked on GitHub Issues and a Projects v2 board. GitHub is the source of truth; the local cache under .secdiagram/tasks/ is a gitignored, read-only snapshot for offline work.
Lifecycle: Backlog -> Ready -> In Progress -> In Review -> Done, with Blocked while waiting on a dependency or decision.
# Create a task and add it to the board
python scripts/taskctl.py new --type feature --title "Add Go manifest detection" \
--priority P1 --area discovery --milestone 0.3.0
# Move through the lifecycle
python scripts/taskctl.py start <issue>
python scripts/taskctl.py block <issue> --reason "waiting on upstream API"
python scripts/taskctl.py review <issue>
python scripts/taskctl.py done <issue> --evidence-file evidence.md
# Refresh and validate the offline cache
python scripts/taskctl.py sync
python scripts/taskctl.py validate --offline
Pull requests must reference an issue with Closes #N; the tasks-pr-check.yml workflow fails otherwise. See docs/TASK_TRACKING.md for one-time setup, board fields, and troubleshooting.
secdiagram/
├── secdiagram_core/ # Core library (Zero external runtime dependencies)
│ ├── __init__.py # Version, schema, and public exports
│ ├── analyzer.py # Orchestrates repo discovery, AST indexing, and analysis
│ ├── ast_index.py # Python AST parser (classes, functions, calls, imports)
│ ├── cli.py # Command-line entrypoint and argument parser
│ ├── discover.py # File walking, gitignore parsing, polyglot manifest detection
│ ├── features.py # Feature grouping and subsystem association
│ ├── frameworks.py # Framework detection (FastAPI, Flask, Django, etc.)
│ ├── graph_builder.py # Builds dependency graph, pruning, edge weighting
│ ├── high_level.py # Compiles C4 high-level tier overview diagrams
│ ├── iac.py # Infrastructure-as-Code audits (Dockerfile, Compose, K8s, TF)
│ ├── llm.py # Citation-preserving LLM narrative review generator
│ ├── model.py # Graph, Node, Edge, Finding, and stable_id data models
│ ├── render_image.py # PNG, SVG, PDF image generation (local mmdc / Kroki / ink)
│ ├── render_json.py # Structured JSON output serializer
│ ├── render_markdown.py # Architecture document generator (ARCHITECTURE.md)
│ ├── render_mermaid.py # Mermaid flowchart code generator (diagram.mmd)
│ ├── render_sarif.py # OASIS SARIF v2.1.0 security report serializer
│ ├── resolver.py # Qualified symbol resolution and call attribution
│ └── security.py # SAST security rules (taint flow, hardcoded secrets, injection)
├── tests/ # Test suite
│ ├── fixtures/ # Sample applications (Python, .NET, Node.js)
│ ├── test_cli.py # CLI integration tests
│ ├── test_discover.py # Discovery & gitignore tests
│ ├── test_graph.py # Graph construction & pruning tests
│ ├── test_high_level.py # High-level C4 diagram tests
│ ├── test_image.py # Image rendering and provider tests
│ ├── test_llm.py # Ollama and LLM narrative tests
│ ├── test_python_index.py # AST indexing & resolver tests
│ ├── test_render.py # Renderers verification
│ └── test_security.py # SAST heuristics & secret scanner tests
├── .github/
│ ├── dependabot.yml # Automated dependency updates
│ └── workflows/
│ ├── ci.yml # Multi-version Python CI, lint, SAST, Trivy
│ ├── codeql.yml # GitHub CodeQL static analysis
│ ├── docker.yml # Container build & security scan
│ └── release.yml # Automated release and Docker Hub delivery
├── Dockerfile # Hardened multi-stage unprivileged container
├── docker-compose.yml # Container run orchestration
└── pyproject.toml # Package build metadata & tool configurations
dependencies = [] in pyproject.toml.ast, urllib, dataclasses, hashlib, json, pathlib, re, shutil, tempfile, subprocess).stable_id(*parts).set or dict.keys() where order influences output files.pathlib.Path for filesystem operations./) so diagrams and SARIF reports remain byte-for-byte identical across Linux, macOS, and Windows.str | None instead of Optional[str].list[str], dict[str, Any], set[int].collections.abc (e.g. from collections.abc import Iterable, Sequence), not from typing.eval(), exec(), or dynamically __import__() untrusted user code.hashlib.sha1), always pass usedforsecurity=False to comply with FIPS and Bandit security gates:
digest = hashlib.sha1(data.encode("utf-8"), usedforsecurity=False).hexdigest()
['mmdc', '-i', ...]): never use shell=True. Set explicit execution timeouts.timeout on urllib.request.urlopen.dependencies = [] empty; the runtime remains standard-library only.== version in pyproject.toml. Never use ranges, >=, or latest.@sha256: digest.docker/mermaid/package-lock.json using npm ci --omit=dev; never use floating npm install in the image build.vserey/secdiagram) require that all CRITICAL and HIGH severity image vulnerabilities are resolved prior to push.secdiagram's container environment (e.g. dead code, lack of network ingress, unprivileged UID 10001 user execution) before publication is permitted..trivyignore.yaml, generated by scripts/refresh_image_baseline.py from a Trivy JSON report. Each entry requires a statement and an expired_at date; fixable findings are rejected by the generator and always block the gate. Refresh the baseline and docs/IMAGE_SECURITY_BASELINE.md each release.| Branch | Purpose | Direct commits | Promotion |
|---|---|---|---|
| main | Stable, release-ready | Never | develop → main via release PR |
| develop | Integration | Never | Feature branches merged locally |
| feat/..., fix/..., ci/..., docs/... | Short-lived work | Yes | PR or local merge into develop |
develop and keep it current with origin/develop before starting.develop must always contain the latest main.develop locally only after the full verification suite passes; push develop after a clean merge.develop to main only when a release is ready and all CI gates pass.main after the release merge is verified.main back into develop; the develop-sync.yml workflow does this automatically and fails loudly on conflicts.main, develop, or any shared branch.Create or select a task: Open a GitHub issue (or run python scripts/taskctl.py new ...) and move it to In Progress with python scripts/taskctl.py start <issue>.
Fork and branch from develop:
git fetch origin
git checkout develop
git merge --ff-only origin/develop
git checkout -b feat/add-go-manifest-detection
# or
git checkout -b fix/sanitize-mermaid-subgraph-ids
Develop and test:
tests/ covering new functionality and edge cases.python -m unittest discover -s tests -v.ruff check ..mypy.python -m bandit -r secdiagram_core -lll.python scripts/taskctl.py validate --offline.docker build -t secdiagram:verify . && docker run --rm secdiagram:verify --helptrivy image --severity CRITICAL,HIGH --ignorefile .trivyignore.yaml --exit-code 1 secdiagram:verifyVerify Git Hygiene:
.env files, temporary screenshots, or dump files are staged:
git status
git diff --cached
.secdiagram/tasks/ is not staged; it is a local, read-only cache.Submit PR: Open a Pull Request targeting the develop branch. Provide a clear description of:
Closes #N.In Review with python scripts/taskctl.py review <issue> before requesting review.Release promotion: Maintainers merge develop into main via a release Pull Request only when the release is ready, then tag the verified commit on main.
We adhere to the Conventional Commits specification:
feat: A new feature or capability.fix: A bug fix.docs: Documentation updates.test: Adding or updating tests.refactor: Code changes that neither fix a bug nor add a feature.ci: Changes to CI/CD workflows, build scripts, or release automation.perf: Performance improvements.Example:
feat: add detection for Go modules and Gin route endpoints
- Parse go.mod for module identity and direct dependencies
- Map Gin engine HTTP route bindings to presentation tier
- Add unit tests covering go.mod parsing
We take security seriously. If you discover a security vulnerability in secdiagram, please do not disclose it publicly in an issue or forum.
Instead, please report it privately:
vichhaiyserey@gmail.com.Include:
We will acknowledge receipt within 48 hours and work with you on a coordinated fix and disclosure schedule.
Then run powershell -ExecutionPolicy Bypass -File .\setup.ps1. It stops at the first error and is safe to run again. Servers and tests aren't started; it lists them at the end. Read it first.
Needs Git: winget install Git.Git
git clone https://github.com/vichhaiyserey/secdiagram.git cd secdiagram
Python >=3.10, Docker
winget install Python.Python.3.10 winget install Docker.DockerDesktop
python -m venv .venv .venv\Scripts\Activate.ps1 pip install -e .
Because secdiagram requires only the Python standard library, run it directly without installing third-party dependencies:
# Analyze current repository and generate detailed architecture diagrams:
python secdiagram.py --dir="."
# Generate both detailed and high-level C4 system diagrams with PNG images:
python secdiagram.py --dir="." --image
# Generate high-level system overview as primary diagram:
python secdiagram.py --dir="." --high-level --image
Run using the pre-built, hardened non-root container with bundled Chromium and Mermaid CLI:
# Linux / macOS:
docker run --rm -v "$(pwd):/repo" secdiagram:local --image
# Windows PowerShell:
docker run --rm -v "${PWD}:/repo" secdiagram:local --image
# RHEL / Fedora (SELinux mode):
docker run --rm -v "$(pwd):/repo:z" secdiagram:local --image
Integrate directly into custom automation scripts or DevSecOps pipelines:
from secdiagram_core import analyze, render_mermaid, AnalysisConfig
result = analyze(AnalysisConfig(root=".", security=True))
print(f"Discovered {len(result.graph.nodes)} nodes and {len(result.graph.findings)} findings.")
# Native taint and package reachability query:
if result.has_taint_at("app/api.py", line=42):
print("Tainted dataflow detected at line 42!")
No reports for Windows yet.
GitManual AI Agent reads the 11 key files and writes a step-by-step guide for Windows. Once written, it's saved for everyone.