feat: Add Playbook Manager, Saved Searches, and Timeline View components

- Implemented PlaybookManager for creating and managing investigation playbooks with templates.
- Added SavedSearches component for managing bookmarked queries and recurring scans.
- Introduced TimelineView for visualizing forensic event timelines with zoomable charts.
- Enhanced backend processing with auto-queued jobs for dataset uploads and improved database concurrency.
- Updated frontend components for better user experience and performance optimizations.
- Documented changes in update log for future reference.
This commit is contained in:
2026-02-23 14:23:07 -05:00
parent 37a9584d0c
commit 5a2ad8ec1c
110 changed files with 10537 additions and 1185 deletions

View File

@@ -1,4 +1,4 @@
"""Application configuration single source of truth for all settings.
"""Application configuration - single source of truth for all settings.
Loads from environment variables with sensible defaults for local dev.
"""
@@ -13,12 +13,12 @@ from pydantic import Field
class AppConfig(BaseSettings):
"""Central configuration for the entire ThreatHunt application."""
# ── General ────────────────────────────────────────────────────────
# -- General --------------------------------------------------------
APP_NAME: str = "ThreatHunt"
APP_VERSION: str = "0.3.0"
DEBUG: bool = Field(default=False, description="Enable debug mode")
# ── Database ───────────────────────────────────────────────────────
# -- Database -------------------------------------------------------
DATABASE_URL: str = Field(
default="sqlite+aiosqlite:///./threathunt.db",
description="Async SQLAlchemy database URL. "
@@ -26,17 +26,17 @@ class AppConfig(BaseSettings):
"postgresql+asyncpg://user:pass@host/db for production.",
)
# ── CORS ───────────────────────────────────────────────────────────
# -- CORS -----------------------------------------------------------
ALLOWED_ORIGINS: str = Field(
default="http://localhost:3000,http://localhost:8000",
description="Comma-separated list of allowed CORS origins",
)
# ── File uploads ───────────────────────────────────────────────────
# -- File uploads ---------------------------------------------------
MAX_UPLOAD_SIZE_MB: int = Field(default=500, description="Max CSV upload in MB")
UPLOAD_DIR: str = Field(default="./uploads", description="Directory for uploaded files")
# ── LLM Cluster Wile & Roadrunner ────────────────────────────────
# -- LLM Cluster - Wile & Roadrunner --------------------------------
OPENWEBUI_URL: str = Field(
default="https://ai.guapo613.beer",
description="Open WebUI cluster endpoint (OpenAI-compatible API)",
@@ -58,7 +58,7 @@ class AppConfig(BaseSettings):
default=11434, description="Ollama port on Roadrunner"
)
# ── LLM Routing defaults ──────────────────────────────────────────
# -- LLM Routing defaults ------------------------------------------
DEFAULT_FAST_MODEL: str = Field(
default="llama3.1:latest",
description="Default model for quick chat / simple queries",
@@ -80,18 +80,18 @@ class AppConfig(BaseSettings):
description="Default embedding model",
)
# ── Agent behaviour ───────────────────────────────────────────────
# -- Agent behaviour ------------------------------------------------
AGENT_MAX_TOKENS: int = Field(default=2048, description="Max tokens per agent response")
AGENT_TEMPERATURE: float = Field(default=0.3, description="LLM temperature for guidance")
AGENT_HISTORY_LENGTH: int = Field(default=10, description="Messages to keep in context")
FILTER_SENSITIVE_DATA: bool = Field(default=True, description="Redact sensitive patterns")
# ── Enrichment API keys ───────────────────────────────────────────
# -- Enrichment API keys --------------------------------------------
VIRUSTOTAL_API_KEY: str = Field(default="", description="VirusTotal API key")
ABUSEIPDB_API_KEY: str = Field(default="", description="AbuseIPDB API key")
SHODAN_API_KEY: str = Field(default="", description="Shodan API key")
# ── Auth ──────────────────────────────────────────────────────────
# -- Auth -----------------------------------------------------------
JWT_SECRET: str = Field(
default="CHANGE-ME-IN-PRODUCTION-USE-A-REAL-SECRET",
description="Secret for JWT signing",
@@ -99,6 +99,73 @@ class AppConfig(BaseSettings):
JWT_ACCESS_TOKEN_MINUTES: int = Field(default=60, description="Access token lifetime")
JWT_REFRESH_TOKEN_DAYS: int = Field(default=7, description="Refresh token lifetime")
# -- Triage settings ------------------------------------------------
TRIAGE_BATCH_SIZE: int = Field(default=25, description="Rows per triage LLM batch")
TRIAGE_MAX_SUSPICIOUS_ROWS: int = Field(
default=200, description="Stop triage after this many suspicious rows"
)
TRIAGE_ESCALATION_THRESHOLD: float = Field(
default=5.0, description="Risk score threshold for escalation counting"
)
# -- Host profiler settings -----------------------------------------
HOST_PROFILE_CONCURRENCY: int = Field(
default=3, description="Max concurrent host profile LLM calls"
)
# -- Scanner settings -----------------------------------------------
SCANNER_BATCH_SIZE: int = Field(default=500, description="Rows per scanner batch")
SCANNER_MAX_ROWS_PER_SCAN: int = Field(
default=120000,
description="Global row budget for a single AUP scan request (0 = unlimited)",
)
# -- Job queue settings ----------------------------------------------
JOB_QUEUE_MAX_BACKLOG: int = Field(
default=2000, description="Soft cap for queued background jobs"
)
JOB_QUEUE_RETAIN_COMPLETED: int = Field(
default=3000, description="Maximum completed/failed jobs to retain in memory"
)
JOB_QUEUE_CLEANUP_INTERVAL_SECONDS: int = Field(
default=60, description="How often to run in-memory job cleanup"
)
JOB_QUEUE_CLEANUP_MAX_AGE_SECONDS: int = Field(
default=3600, description="Age threshold for in-memory completed job cleanup"
)
# -- Startup throttling ------------------------------------------------
STARTUP_WARMUP_MAX_HUNTS: int = Field(
default=5, description="Max hunts to warm inventory cache for at startup"
)
STARTUP_REPROCESS_MAX_DATASETS: int = Field(
default=25, description="Max unprocessed datasets to enqueue at startup"
)
STARTUP_RECONCILE_STALE_TASKS: bool = Field(
default=True,
description="Mark stale queued/running processing tasks as failed on startup",
)
# -- Network API scale guards -----------------------------------------
NETWORK_SUBGRAPH_MAX_HOSTS: int = Field(
default=400, description="Hard cap for hosts returned by network subgraph endpoint"
)
NETWORK_SUBGRAPH_MAX_EDGES: int = Field(
default=3000, description="Hard cap for edges returned by network subgraph endpoint"
)
NETWORK_INVENTORY_MAX_ROWS_PER_DATASET: int = Field(
default=5000,
description="Row budget per dataset when building host inventory (0 = unlimited)",
)
NETWORK_INVENTORY_MAX_TOTAL_ROWS: int = Field(
default=120000,
description="Global row budget across all datasets for host inventory build (0 = unlimited)",
)
NETWORK_INVENTORY_MAX_CONNECTIONS: int = Field(
default=120000,
description="Max unique connection tuples retained during host inventory build",
)
model_config = {"env_prefix": "TH_", "env_file": ".env", "extra": "ignore"}
@property
@@ -119,3 +186,4 @@ class AppConfig(BaseSettings):
settings = AppConfig()