Skip to content

Design Decisions

Why These Choices Were Made

FastAPI (not Flask/Django)

  • Async support for Pi-hole API calls
  • Built-in request validation with Pydantic
  • Auto-generated OpenAPI docs at /docs
  • Lightweight — no ORM, no template engine needed

Vanilla Frontend (no React/Vue)

  • Single HTML file — no build step, no Node.js required
  • Immediate deployment — change the file, reload the browser
  • Zero dependencies — works offline, no CDN required
  • Full control over every pixel

Host Network Mode

The Control Center needs:

  • iptables access to manage firewall rules
  • wg show to read WireGuard status
  • Direct port binding for FastAPI
  • Access to the host's kernel log for blocked traffic

Docker's host network mode gives all of this without complex networking.

JSON-lines for Audit Log (not SQLite/DB)

  • Append-only — no corruption risk from concurrent writes
  • Line-based — grep, tail, jq for analysis
  • No dependencies — no database to configure
  • Rotatable — simple line-count-based rotation
  • Compatible with log aggregation pipelines (ELK, Loki)

iptables Chain (not nftables)

  • Docker itself uses iptables (compatibility)
  • iptables command is available everywhere
  • VM_EGRESS chain is isolated — doesn't interfere with Docker or UFW
  • Simple rule syntax for the use case

MkDocs Material (not Docusaurus/GitBook)

  • Python-based — matches the Control Center tech stack
  • Official Docker image (squidfunk/mkdocs-material)
  • Beautiful dark theme built-in
  • Mermaid diagrams, admonitions, code highlighting
  • Reads plain Markdown — no build step beyond mkdocs serve

Three WireGuard Tunnels (not one)

  • Separation of concerns — admin access vs. AI access vs. VM access
  • Security isolation — strato-vm and openclaw-ai can't reach the host (INPUT DROP)
  • Different client devices — laptop tunnels vs. local VM tunnel
  • Independent key rotation — compromise of one doesn't affect others

NeMo Guardrails Inspiration (not full integration)

NeMo Guardrails is designed for LLM conversation-level safety (input rails, output rails, topical boundaries). Our infrastructure operates at a completely different layer (network, firewall, containers).

We adopted the concepts, not the code:

NeMo Concept Our Implementation
Rail activation tracking Structured audit logging
Security pipeline visualization Dashboard security pipeline
Decision reasoning in logs Event severity + details JSON
Configurable policies Access profiles (Locked → Unrestricted)

This provides the same observability benefits without forcing an LLM-specific framework into infrastructure tooling.