BOL System Architecture Document

Deployment topology, security architecture, data flow, technology stack, and operational procedures.

Download PDF
1. System Overview

1.1 Purpose

This document describes the system architecture of BOL (Beginning of Life), a full-stack Python application that simulates prebiotic chemistry and the emergence of the first protocells. It covers the deployment topology, component interactions, security architecture, data flow, technology stack, and operational procedures.

1.2 System Context

BOL operates as a single-server web application serving a browser-based dashboard. The system has no external database dependencies — all persistent data is stored as JSON files on the local filesystem. The simulation engine runs in-process alongside the web server.

1.3 Key Characteristics

  • Self-contained — No external databases, message queues, or microservices.
  • Single-process — Flask app + simulation thread in one Python process (Gunicorn multi-worker in production).
  • File-based persistence — JSON files for users, projects, scenarios, training, and bugs.
  • Real-time — Polling-based live updates from running simulation to browser.
2. Deployment Topology

2.1 Production Architecture

  ┌───────────────────────────────────────────────────────┐
  │                  Client (Browser / PWA)                │
  │   • Dashboard, Microscope, AI Lab, Projects, etc.     │
  │   • Chart.js, Three.js, vanilla JS                    │
  └──────────────────────┬────────────────────────────────┘
                         │ HTTPS (443)
  ┌──────────────────────▼────────────────────────────────┐
  │              Nginx Reverse Proxy                       │
  │   • SSL termination (Let's Encrypt)                   │
  │   • bol.drel.us → 127.0.0.1:5000                     │
  │   • drel.us → static HTML landing page                │
  │   • Security headers (CSP, HSTS, X-Frame-Options)     │
  │   • Static file serving (/static/ → /opt/bol/...)     │
  │   • 10 MB upload limit                                │
  └──────────────────────┬────────────────────────────────┘
                         │ HTTP (5000, localhost only)
  ┌──────────────────────▼────────────────────────────────┐
  │         Gunicorn WSGI Server                           │
  │   • 3 worker processes                                │
  │   • 120-second request timeout                        │
  │   • Managed by systemd (bol.service)                  │
  │   • Auto-restart on failure (RestartSec=5)            │
  └──────────────────────┬────────────────────────────────┘
                         │
  ┌──────────────────────▼────────────────────────────────┐
  │         Flask Application (bol.web.server)             │
  │   • Page routes (30+ HTML templates)                  │
  │   • REST API endpoints (40+ routes)                   │
  │   • Authentication & session management               │
  │   • Security middleware (headers, rate limiting)       │
  │   • PDF document generation                           │
  ├───────────────────────────────────────────────────────┤
  │         Simulation Engine (background thread)          │
  │   • Stochastic chemistry (27 reactions)               │
  │   • Self-assembly (micelles → vesicles)               │
  │   • RNA replication with mutations                    │
  │   • Metrics collection & export                       │
  ├───────────────────────────────────────────────────────┤
  │         File System Storage                            │
  │   • profiles/*.json    (user accounts)                │
  │   • projects/*.json    (experiment projects)          │
  │   • scenarios/*.json   (4 preset scenarios)           │
  │   • training/modules.json (curriculum)                │
  │   • bugs/bugs.json     (bug tracker)                  │
  │   • .secret_key        (session signing key)          │
  │   • output/            (CSV/JSON exports)             │
  └───────────────────────────────────────────────────────┘

  Target: GCP Compute Engine (e2-small, Ubuntu 24.04 LTS)
  Domains: drel.us (landing), bol.drel.us (app)

2.2 Local Development

  Browser ──► http://127.0.0.1:5000 ──► Flask dev server (single thread)
                                        │
                                        ├── Simulation (background thread)
                                        └── File system (profiles/, projects/, etc.)

Local mode differences: no Nginx, no SSL, no Gunicorn, SESSION_COOKIE_SECURE=False.

2.3 Network Configuration

PortProtocolServiceAccess
22TCPSSHAdmin only (key-based auth)
80TCPHTTPPublic (redirects to 443)
443TCPHTTPSPublic (Nginx → Gunicorn)
5000TCPGunicornLocalhost only (127.0.0.1)
3. Security Architecture

3.1 NIST SP 800-53 Control Mapping

ControlTitleImplementation
AC-7Unsuccessful Login AttemptsIP-based rate limiting: 10 attempts per 5-minute window; returns 429 on excess
IA-5Authenticator ManagementPBKDF2-HMAC-SHA256, 260K iterations, 32-byte salt; min 8 chars + upper/lower/digit
SC-8Transmission ConfidentialityTLS 1.2+ via Let’s Encrypt; HSTS with 1-year max-age
SC-13Cryptographic ProtectionPBKDF2 for passwords; secrets.token_hex for session keys; timing-safe comparison
SI-10Information Input ValidationAllowlist validation on all user-supplied identifiers (usernames, IDs, filenames)
SI-11Error HandlingGeneric error messages to users; detailed errors logged server-side only
AC-3Access EnforcementResource ownership enforcement; admin-only endpoints; session-based auth
AU-2Audit EventsGunicorn access/error logs; simulation event logging

3.2 CISA Compliance

DirectiveRequirementImplementation
BOD 18-01HTTPS enforcementNginx redirects HTTP→HTTPS; HSTS header; Secure cookie flag in production
BOD 22-01Known exploited vulnerabilitiesDependencies pinned to recent versions; regular updates via pip

3.3 Security Headers

Applied by both Flask middleware (@app.after_request) and Nginx:

HeaderValuePurpose
Content-Security-Policydefault-src 'self'; script-src 'self' 'unsafe-inline' cdn...; ...Prevent XSS, data exfiltration
Strict-Transport-Securitymax-age=31536000; includeSubDomainsForce HTTPS for 1 year
X-Content-Type-OptionsnosniffPrevent MIME sniffing
X-Frame-OptionsSAMEORIGINPrevent clickjacking
Referrer-Policystrict-origin-when-cross-originLimit referrer leakage
Permissions-Policycamera=(), microphone=(), geolocation=(), payment=()Disable unnecessary browser APIs
X-XSS-Protection1; mode=blockLegacy XSS filter activation

3.4 Authentication & Session Security

  • Password storage — PBKDF2-HMAC-SHA256, 260,000 iterations, 32-byte random salt per user.
  • Password policy — Minimum 8 characters; must contain uppercase letter, lowercase letter, and digit.
  • Session cookies — HttpOnly (no JS access), SameSite=Lax (CSRF mitigation), Secure (production only).
  • Session lifetime — 8-hour expiry with PERMANENT_SESSION_LIFETIME.
  • Secret key persistence — Session signing key stored in .secret_key file (gitignored); sessions survive server restarts.
  • Timing-safe comparisonsecrets.compare_digest() for password verification prevents timing attacks.

3.5 Input Validation & Output Encoding

  • Server-side — Usernames validated against [a-zA-Z0-9_-] allowlist. Project IDs, lesson IDs, and filenames sanitised before filesystem access. JSON request bodies parsed with schema validation.
  • Template engine — Jinja2 auto-escaping enabled globally. No |safe filter usage in templates.
  • Client-sideescHtml() / _esc() helper functions and textContent used for safe DOM updates. All user-supplied strings escaped before insertion.
  • Command injection preventionshlex.split() with shell=False for subprocess execution. URL scheme validation (HTTP/HTTPS only) prevents SSRF.
4. Technology Stack

4.1 Backend

LayerTechnologyVersionRole
LanguagePython3.12+All server-side code
Web FrameworkFlask≥3.0HTTP routing, templating, sessions
WSGI ServerGunicornLatestProduction multi-worker serving
Reverse ProxyNginxLatestSSL termination, static files, headers
NumericalNumPy≥1.24Vectorised simulation computations
StatisticalSciPy≥1.10Metrics computation
PlottingMatplotlib≥3.7CLI chart generation
3D DesktopVispy≥0.14GPU-accelerated particle rendering

4.2 Frontend

TechnologyRole
Jinja2Server-side HTML templating with auto-escaping
Vanilla JavaScriptDashboard polling, DOM manipulation, event handling
Chart.js (CDN)Line, bar, and pie charts for real-time metrics
Three.js (CDN)WebGL 3D particle viewer with vesicle shells
Font Awesome 6 (CDN)Icon library
CSS3 Custom PropertiesSplunk-themed dark UI with responsive breakpoints
Canvas 2D APIProcedural microscope renderer (9 magnification levels)
Web Speech APIText-to-speech for training lesson reader
Service WorkerPWA offline caching and install-to-home-screen

4.3 Infrastructure

ComponentTechnologyDetails
CloudGCP Compute Enginee2-small (2 vCPU, 2 GB RAM)
OSUbuntu 24.04 LTSLong-term support until 2034
Process ManagersystemdAuto-restart, env vars, logging
SSLLet’s Encrypt + certbotAuto-renewal via cron
FirewallufwAllow SSH (22), HTTP (80), HTTPS (443)
Data StorageLocal filesystemJSON files, no external database
5. Data Flow Architecture

5.1 Request/Response Flow

  Browser ──HTTPS──► Nginx ──HTTP──► Gunicorn ──► Flask Route
                                                    │
                                        ┌───────────┴───────────┐
                                        ▼                       ▼
                                   Page Route              API Route
                                   (Jinja2 → HTML)        (→ JSON)
                                                              │
                                                    ┌─────────┴────────┐
                                                    ▼                  ▼
                                              Read/Write          Simulation
                                              JSON files          state query

5.2 Simulation Data Flow

  Config ──► Simulation.init()
                 │
         ┌───────┴──────────────────────────────────────┐
         │  Step Loop (background thread)                │
         │  ┌─────────────────────────────────────────┐  │
         │  │  1. world.diffuse(molecules)            │  │
         │  │  2. energy.update(world)                │  │
         │  │  3. chemistry.react(molecules, world)   │  │
         │  │  4. assembly.step(molecules, world)     │  │
         │  │  5. replication.step(molecules, world)  │  │
         │  │  6. metrics.compute(molecules, ...)     │  │
         │  └─────────────────────────────────────────┘  │
         │                     │                         │
         │              metrics_history[]                 │
         └───────────────────┬──────────────────────────┘
                             │
                     ┌───────┴──────────┐
                     ▼                  ▼
              GET /api/state      GET /api/history
              (latest record)     (time series)

5.3 Authentication Flow

  1. POST /api/profile/login with {"username": "...", "password": "..."}
  2. Server checks rate limit (IP-based, 10/5min window)
  3. Server loads profile JSON, computes PBKDF2 hash with stored salt
  4. Timing-safe comparison with stored hash (secrets.compare_digest)
  5. On success: set session["username"], session.permanent = True, return 200
  6. On failure: return 401 with generic error message, record attempt
6. Operational Procedures

6.1 Service Management

# Check service status
sudo systemctl status bol

# Restart the application
sudo systemctl restart bol

# View application logs
sudo journalctl -u bol -f
tail -f /var/log/bol-access.log
tail -f /var/log/bol-error.log

# Check Nginx
sudo nginx -t
sudo systemctl reload nginx

6.2 Deployment Update Procedure

  1. Run tests locally: python -m pytest tests/ -v
  2. Deploy to server: .\deploy\deploy_to_server.ps1
  3. SSH to server and restart service: sudo systemctl restart bol
  4. Verify HTTPS endpoint is responding
  5. Check logs for errors: sudo journalctl -u bol --since "5 minutes ago"

6.3 SSL Certificate Renewal

Certbot is configured for automatic renewal via cron/systemd timer. Manual renewal:

sudo certbot renew --dry-run    # Test renewal
sudo certbot renew              # Actual renewal

6.4 Backup Strategy

  • Code — Git repository; deploy from local machine via rsync.
  • User dataprofiles/, projects/, bugs/, training/ directories. Should be backed up periodically.
  • Secret key.secret_key file. Loss invalidates all active sessions (users must re-login).

6.5 Monitoring

  • Uptime — systemd auto-restart with RestartSec=5 recovers from crashes within seconds.
  • Access logging — Gunicorn access log at /var/log/bol-access.log.
  • Error logging — Gunicorn error log at /var/log/bol-error.log.
  • Firewall — ufw allows only ports 22, 80, 443; all others denied by default.
7. Scalability Considerations

7.1 Current Capacity

  • Concurrent users — Gunicorn’s 3 workers can serve ~50 concurrent browser sessions.
  • Simulation size — Up to ~10,000 molecules per simulation with acceptable step latency.
  • Storage — JSON files are lightweight; thousands of projects and profiles feasible on SSD.

7.2 Scaling Options

  • Vertical — Upgrade to larger GCP instance (e2-medium or e2-standard) for more CPU/RAM.
  • Worker processes — Increase Gunicorn workers (currently 3) to match available CPU cores.
  • Database migration — If file-based storage becomes a bottleneck, migrate to SQLite or PostgreSQL.
  • CDN — Serve static assets via CloudFlare or GCP Cloud CDN for global performance.