# Flowfish - System Architecture
This document describes the technical architecture of the Flowfish platform in detail.
## π Table of Contents
- [Overview](#overview)
- [Logical Architecture](#logical-architecture)
- [Physical Architecture](#physical-architecture)
- [Data Flow Diagrams](#data-flow-diagrams)
- [Component Details](#component-details)
- [Data Model](#database-schemas-high-level)
- [API Architecture](#api-architecture)
- [Deployment Architecture](#deployment-architecture)
---
## Overview
Flowfish is a Kubernetes/OpenShift-native platform designed according to microservice architecture principles. It delivers a high-performance, scalable solution through eBPF-based data collection, multi-database usage, and modern web technologies.
### Core Principles
1. **Cloud-Native**: Optimized for Kubernetes/OpenShift
2. **Scalable**: Horizontal scaling support
3. **Resilient**: Fault-tolerant, self-healing
4. **Observable**: Comprehensive logging, metrics, tracing
5. **Secure**: Multi-tenant, RBAC, encryption
6. **Modular**: Loosely coupled components
---
## Logical Architecture
### Architecture Layers
Flowfish consists of 5 main layers:
```mermaid
graph TB
subgraph "Presentation Layer"
UI[React Frontend]
API_GW[API Gateway/Ingress]
end
subgraph "Application Layer"
AUTH[Authentication Service]
ANALYSIS[Analysis Orchestrator]
GRAPH_SVC[Graph Service]
EXPORT[Import/Export Service]
LLM[LLM Integration Service]
SCHEDULER[Scheduler Service]
CHANGE_WORKER[Change Detection Worker]
end
subgraph "Data Collection Layer"
IG[Inspektor Gadget DaemonSet - L4]
BEYLA[Grafana Beyla DaemonSet - L7]
L7_COLLECTOR[flowfish-l7-collector]
COLLECTOR[Data Collector]
ENRICHER[Data Enricher]
L7_INGESTION[L7 Ingestion Service]
end
subgraph "Data Layer"
PG[(PostgreSQL)]
NEO4J[(Neo4j)]
CH[(ClickHouse)]
REDIS[(Redis Cache)]
end
subgraph "Infrastructure Layer"
K8S[Kubernetes/OpenShift]
STORAGE[Persistent Storage]
NETWORK[Network Fabric]
end
UI --> API_GW
API_GW --> AUTH
API_GW --> ANALYSIS
API_GW --> GRAPH_SVC
API_GW --> EXPORT
ANALYSIS --> SCHEDULER
ANALYSIS --> LLM
ANALYSIS --> IG
ANALYSIS --> L7_INGESTION
BEYLA --> L7_COLLECTOR
L7_INGESTION --> L7_COLLECTOR
GRAPH_SVC --> NEO4J
GRAPH_SVC --> REDIS
IG --> COLLECTOR
COLLECTOR --> ENRICHER
ENRICHER --> PG
ENRICHER --> NEO4J
ENRICHER --> CH
AUTH --> PG
EXPORT --> PG
EXPORT --> NEO4J
LLM --> PG
CHANGE_WORKER --> PG
CHANGE_WORKER --> NEO4J
CHANGE_WORKER --> REDIS
K8S --> STORAGE
K8S --> NETWORK
style UI fill:#1890ff,color:#fff
style API_GW fill:#1890ff,color:#fff
style AUTH fill:#52c41a,color:#fff
style ANALYSIS fill:#52c41a,color:#fff
style GRAPH_SVC fill:#52c41a,color:#fff
style CHANGE_WORKER fill:#eb2f96,color:#fff
style IG fill:#fa8c16,color:#fff
style COLLECTOR fill:#fa8c16,color:#fff
style PG fill:#722ed1,color:#fff
style NEO4J fill:#722ed1,color:#fff
style CH fill:#722ed1,color:#fff
style K8S fill:#13c2c2,color:#fff
```
### Layer Descriptions
#### 1. Presentation Layer
**React Frontend:**
- Single Page Application (SPA)
- Ant Design component library
- Cytoscape.js for graph visualization
- Redux for state management
- Axios for API communication
- WebSocket for real-time updates
**API Gateway/Ingress:**
- Nginx Ingress Controller
- TLS termination
- Rate limiting
- Request routing
- Load balancing
#### 2. Application Layer
**Authentication Service:**
- JWT token generation/validation
- OAuth 2.0 provider integration
- Kubernetes SA authentication
- Session management
- RBAC enforcement
- **Authentication methods:** JWT (Bearer) and API keys via the `X-API-Key` header are both supported for programmatic and UI access.
**Analysis Orchestrator:**
- Wizard workflow management
- Analysis lifecycle management (start, stop, monitor)
- Scope-based filtering
- Gadget module configuration
- Result aggregation
**Graph Service:**
- Neo4j query execution
- Graph traversal algorithms
- Real-time graph updates
- Graph snapshot management
- Graph export/import
**Import/Export Service:**
- CSV parsing and generation
- Graph JSON serialization
- Batch processing
- Format validation
- Version control
**LLM Integration Service:**
- LLM provider abstraction (OpenAI, Azure, Anthropic)
- Prompt engineering
- Response parsing
- Anomaly scoring
- Context window management
**Scheduler Service:**
- Cron-based job scheduling
- Periodic analysis execution
- Baseline creation jobs
- Export automation
- Report generation
**Change Detection Worker (Scalable Microservice):**
- Standalone Pod deployment
- Horizontally scalable with leader election (Redis)
- Periodic infrastructure change detection
- Workload and connection change monitoring
- Risk assessment and blast radius calculation
- Real-time WebSocket notifications for critical changes
- Circuit breaker pattern for resilience
- **Hybrid Storage Architecture (NEW):**
- Dual-write: PostgreSQL (ACID) + RabbitMQ/ClickHouse (analytics)
- Run-based filtering (filter changes by analysis run)
- Analysis lifecycle-based data retention (no TTL)
#### 3. Data Collection Layer
**Inspektor Gadget DaemonSet:**
- eBPF program loading
- Kernel event capture
- Pod-level data collection
- Minimal overhead monitoring
- Configurable gadgets (network, DNS, TCP, process, syscall, file)
**Data Collector:**
- Event stream aggregation
- Data buffering
- Batch insertion
- Error handling and retry
- Back-pressure management
**Data Enricher:**
- Kubernetes API integration
- Pod/Deployment/Service metadata enrichment
- Label and annotation extraction
- Namespace and cluster tagging
- IP-to-workload mapping
**Ingestion Service (enrichment):** The Ingestion Service enriches pod records with annotations merged from **pod-level** metadata and from the owning **Deployment** or **StatefulSet**. When the same key exists in both places, **pod annotations take precedence** in the merge.
#### 4. Data Layer
**PostgreSQL:**
- Relational data (users, clusters, analyses, configurations)
- ACID compliance
- Foreign key relationships
- JSONB support for flexible schemas
- Full-text search
**Neo4j:**
- Graph data (workloads as vertices, communications as edges)
- Distributed graph storage
- Fast graph traversal
- Property graph model
- GQL (Graph Query Language)
**ClickHouse:**
- Time-series data (network flows, metrics, events)
- Columnar storage
- High compression ratios
- Fast analytical queries
- Partitioning and sharding
**Redis:**
- Session cache
- Real-time metrics cache
- Rate limiting counters
- Pub/Sub for real-time updates
- Distributed locks
#### 5. Infrastructure Layer
**Kubernetes/OpenShift:**
- Container orchestration
- Service discovery
- Auto-scaling (HPA, VPA)
- Self-healing
- ConfigMaps and Secrets
**Persistent Storage:**
- StatefulSet volumes (databases)
- PersistentVolumeClaims
- Storage classes (SSD, HDD)
- Volume snapshots
- Backup/restore
**Network Fabric:**
- CNI (Container Network Interface)
- Network policies
- Service mesh (optional: Istio, Linkerd)
- Ingress controllers
- Load balancers
---
## Physical Architecture
### Deployment Architecture
```mermaid
graph TB
subgraph "External Access"
USER[π€ End Users]
LLM_PROVIDER[π€ LLM Provider
OpenAI/Azure]
end
subgraph "Kubernetes Cluster"
subgraph "Ingress Layer"
INGRESS[Nginx Ingress
TLS + LoadBalancer]
end
subgraph "Application Pods"
FE1[Frontend Pod 1
React:3000]
FE2[Frontend Pod 2
React:3000]
BE1[Backend Pod 1
FastAPI:8000]
BE2[Backend Pod 2
FastAPI:8000]
BE3[Backend Pod 3
FastAPI:8000]
CW1[Change Worker 1
:8001]
end
subgraph "Cache Layer"
REDIS_M[Redis Master]
REDIS_R1[Redis Replica 1]
REDIS_R2[Redis Replica 2]
end
subgraph "Database Layer"
PG_M[PostgreSQL Master
:5432]
PG_R[PostgreSQL Replica
:5432]
CH_N1[ClickHouse Node 1
:8123]
CH_N2[ClickHouse Node 2
:8123]
CH_N3[ClickHouse Node 3
:8123]
NB_G1[Neo4j
Graphd 1:9669]
NB_G2[Neo4j
Graphd 2:9669]
NB_M1[Neo4j
Metad 1:9559]
NB_M2[Neo4j
Metad 2:9559]
NB_S1[Neo4j
Storaged 1:9779]
NB_S2[Neo4j
Storaged 2:9779]
NB_S3[Neo4j
Storaged 3:9779]
end
subgraph "Data Collection"
IG_N1[Inspektor Gadget
Node 1]
IG_N2[Inspektor Gadget
Node 2]
IG_N3[Inspektor Gadget
Node 3]
end
subgraph "Storage"
PVC_PG[PG Volume
100GB SSD]
PVC_CH[CH Volume
500GB SSD]
PVC_NB[Nebula Volume
200GB SSD]
end
end
USER --> INGRESS
INGRESS --> FE1 & FE2
FE1 & FE2 --> BE1 & BE2 & BE3
BE1 & BE2 & BE3 --> REDIS_M
CW1 --> REDIS_M
REDIS_M --> REDIS_R1 & REDIS_R2
BE1 & BE2 & BE3 --> PG_M
CW1 --> PG_M
PG_M --> PG_R
PG_M --> PVC_PG
BE1 & BE2 & BE3 --> CH_N1 & CH_N2 & CH_N3
CH_N1 & CH_N2 & CH_N3 --> PVC_CH
BE1 & BE2 & BE3 --> NB_G1 & NB_G2
CW1 --> NB_G1 & NB_G2
NB_G1 & NB_G2 --> NB_M1 & NB_M2
NB_M1 & NB_M2 --> NB_S1 & NB_S2 & NB_S3
NB_S1 & NB_S2 & NB_S3 --> PVC_NB
IG_N1 & IG_N2 & IG_N3 --> BE1 & BE2 & BE3
BE1 & BE2 & BE3 --> LLM_PROVIDER
style USER fill:#ffd700,color:#000
style INGRESS fill:#1890ff,color:#fff
style FE1 fill:#52c41a,color:#fff
style FE2 fill:#52c41a,color:#fff
style BE1 fill:#722ed1,color:#fff
style BE2 fill:#722ed1,color:#fff
style BE3 fill:#722ed1,color:#fff
style CW1 fill:#eb2f96,color:#fff
style IG_N1 fill:#fa8c16,color:#fff
style IG_N2 fill:#fa8c16,color:#fff
style IG_N3 fill:#fa8c16,color:#fff
```
### Resource Allocation
#### Frontend (React)
```yaml
Replicas: 2-5 (HPA)
Resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
```
#### Backend (FastAPI)
```yaml
Replicas: 3-10 (HPA)
Resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
```
#### PostgreSQL
```yaml
Replicas: 1 master + 1 replica
Resources:
requests:
cpu: 1000m
memory: 4Gi
limits:
cpu: 4000m
memory: 8Gi
Storage: 100GB SSD (PVC)
```
#### ClickHouse
```yaml
Replicas: 3 nodes (distributed)
Resources (per node):
requests:
cpu: 2000m
memory: 8Gi
limits:
cpu: 8000m
memory: 16Gi
Storage: 500GB SSD per node (PVC)
```
#### Neo4j
```yaml
Graph nodes: 2
Meta nodes: 2
Storage nodes: 3
Resources (per graph/meta):
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 4000m
memory: 8Gi
Resources (per storage):
requests:
cpu: 2000m
memory: 4Gi
limits:
cpu: 8000m
memory: 16Gi
Storage: 200GB SSD per storage node (PVC)
```
#### Redis
```yaml
Replicas: 1 master + 2 replicas
Resources:
requests:
cpu: 500m
memory: 2Gi
limits:
cpu: 2000m
memory: 4Gi
```
#### Inspektor Gadget (DaemonSet)
```yaml
Pods: 1 per node (automatically)
Resources (per pod):
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
```
#### Change Detection Worker
```yaml
Replicas: 1 (single) or 3+ (with leader election)
Resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
Leader Election: Redis-based (optional)
```
---
## Data Flow Diagrams
### 1. Data Collection Flow
Enrichment in this pipeline includes the Ingestion Service behavior described under [Logical Architecture β Data Collection Layer](#3-data-collection-layer): pod annotations merged from the pod and from the owning Deployment/StatefulSet, with pod-level values winning on conflicts.
```mermaid
sequenceDiagram
autonumber
actor User
participant UI as Frontend UI
participant API as Backend API
participant Scheduler
participant K8S as Kubernetes API
participant IG as Inspektor Gadget
participant Collector as Data Collector
participant Enricher as Data Enricher
participant PG as PostgreSQL
participant CH as ClickHouse
participant NB as Neo4j
User->>UI: Start Analysis (Wizard)
UI->>API: POST /api/v1/analyses
API->>PG: Save analysis config
API->>Scheduler: Schedule collection job
Scheduler->>K8S: Get target workloads (scope)
K8S-->>Scheduler: Workload list
Scheduler->>IG: Start gadgets (network, DNS, etc.)
loop Every 5 seconds
IG->>IG: Capture eBPF events
IG->>Collector: Send event batch
Collector->>Enricher: Forward events
Enricher->>K8S: Enrich with metadata
K8S-->>Enricher: Pod/Service metadata
Enricher->>CH: Insert time-series data
Enricher->>PG: Insert/update workloads
Enricher->>NB: Update graph (vertices+edges)
end
User->>UI: View Live Map
UI->>API: GET /api/v1/dependencies/graph
API->>NB: Query graph
NB-->>API: Graph data (JSON)
API-->>UI: Return graph
UI->>UI: Render with Cytoscape.js
```
### 2. Anomaly Detection Flow
```mermaid
sequenceDiagram
autonumber
participant Scheduler
participant API as Backend API
participant PG as PostgreSQL
participant NB as Neo4j
participant LLM as LLM Service
participant PROVIDER as LLM Provider
participant WEBHOOK as External Webhook
Scheduler->>Scheduler: Trigger periodic check (15 min)
Scheduler->>API: Execute anomaly detection
API->>PG: Get baseline data
PG-->>API: Baseline profile
API->>NB: Get recent communications (last 15 min)
NB-->>API: Recent graph data
API->>API: Calculate diff (baseline vs recent)
API->>LLM: Prepare LLM prompt
LLM->>PROVIDER: POST /v1/chat/completions
Note over LLM,PROVIDER: Context: baseline + recent + diff
PROVIDER-->>LLM: AI response (anomalies detected)
LLM->>LLM: Parse response & extract anomalies
LLM-->>API: Anomaly list with scores
loop For each anomaly
API->>PG: Insert anomaly record
alt Severity >= High
API->>WEBHOOK: Send alert webhook
API->>PG: Log alert sent
end
end
API-->>Scheduler: Anomaly detection complete
```
### 3. Import/Export Flow
```mermaid
sequenceDiagram
autonumber
actor User
participant UI as Frontend UI
participant API as Backend API
participant PG as PostgreSQL
participant NB as Neo4j
participant S3 as S3/Storage
Note over User,S3: Export Flow
User->>UI: Click Export (CSV/JSON)
UI->>API: GET /api/v1/export?format=csv&scope=...
API->>NB: Query graph (filtered by scope)
NB-->>API: Graph data
API->>API: Transform to CSV/JSON
API-->>UI: Download file
opt Auto Export Enabled
API->>S3: Upload to S3 bucket
API->>PG: Log export event
end
Note over User,S3: Import Flow
User->>UI: Upload file (CSV/JSON)
UI->>API: POST /api/v1/import (multipart/form-data)
API->>API: Validate file format & schema
alt Validation Failed
API-->>UI: Error response
else Validation Success
API->>PG: Create import job
API->>API: Parse file (async)
loop For each record
API->>PG: Insert/update workload
API->>NB: Insert/update vertex & edge
end
API->>PG: Update import job status (completed)
API-->>UI: Success response
end
```
### 4. Real-Time Update Flow
```mermaid
sequenceDiagram
autonumber
participant IG as Inspektor Gadget
participant Collector as Data Collector
participant REDIS as Redis Pub/Sub
participant API as Backend API
participant WS as WebSocket
participant UI as Frontend UI
UI->>API: Connect WebSocket
API->>WS: Establish connection
API->>REDIS: Subscribe to channel "live-updates"
loop Continuous
IG->>Collector: New event (TCP connection)
Collector->>REDIS: Publish event
REDIS->>API: Receive published event
API->>API: Lightweight processing
API->>WS: Send JSON message
WS->>UI: Push update
UI->>UI: Update graph (add edge, animate)
end
Note over UI: User navigates away
UI->>API: Close WebSocket
API->>REDIS: Unsubscribe
```
---
## Component Details
### Backend API (FastAPI)
#### Technology Stack
- **Framework**: FastAPI 0.100+
- **Language**: Python 3.11+
- **ASGI Server**: Uvicorn
- **Async Libraries**: asyncio, aiohttp, asyncpg
- **ORM**: SQLAlchemy 2.0+ (async)
- **Validation**: Pydantic v2
- **Authentication**: python-jose (JWT), authlib (OAuth)
#### Module Structure
```
backend/
βββ main.py # FastAPI app initialization
βββ config.py # Configuration management
βββ models/ # SQLAlchemy models
β βββ user.py
β βββ cluster.py
β βββ analysis.py
β βββ workload.py
β βββ communication.py
β βββ anomaly.py
β βββ baseline.py
βββ schemas/ # Pydantic schemas (API contracts)
β βββ user_schemas.py
β βββ cluster_schemas.py
β βββ ...
βββ routers/ # API route handlers
β βββ auth.py
β βββ clusters.py
β βββ analyses.py
β βββ workloads.py
β βββ communications.py
β βββ dependencies.py
β βββ anomalies.py
β βββ changes.py
β βββ export.py
β βββ import.py
βββ services/ # Business logic
β βββ auth_service.py
β βββ analysis_service.py
β βββ graph_service.py
β βββ llm_service.py
β βββ export_service.py
β βββ scheduler_service.py
β βββ change_detection_service.py # Change detection core logic
βββ workers/ # Background workers (optional embedded mode)
β βββ __init__.py
β βββ change_detection_worker.py
βββ worker_main.py # Standalone worker entry point
βββ collectors/ # Data collection logic
β βββ gadget_collector.py
β βββ data_enricher.py
β βββ k8s_client.py
βββ database/ # Database connections
β βββ postgresql.py
β βββ clickhouse.py
β βββ neo4j.py
β βββ redis.py
βββ middleware/ # Custom middleware
β βββ auth_middleware.py
β βββ rbac_middleware.py
β βββ logging_middleware.py
β βββ rate_limit_middleware.py
βββ utils/ # Utility functions
β βββ jwt_utils.py
β βββ crypto_utils.py
β βββ date_utils.py
β βββ graph_utils.py
βββ tests/ # Unit & integration tests
β βββ test_auth.py
β βββ test_analyses.py
β βββ ...
βββ requirements.txt # Python dependencies
```
#### API Endpoints (Summary)
```
/api/v1/
βββ auth/
β βββ POST /login
β βββ POST /logout
β βββ POST /refresh
β βββ GET /me
β βββ POST /oauth/{provider}
βββ users/
β βββ GET /
β βββ POST /
β βββ GET /{id}
β βββ PUT /{id}
β βββ DELETE /{id}
βββ clusters/
β βββ GET /
β βββ POST /
β βββ GET /{id}
β βββ PUT /{id}
β βββ DELETE /{id}
β βββ GET /{id}/namespaces
βββ analyses/
β βββ GET /
β βββ POST /
β βββ GET /{id}
β βββ PUT /{id}
β βββ DELETE /{id}
β βββ POST /{id}/start
β βββ POST /{id}/stop
β βββ GET /{id}/status
βββ workloads/
β βββ GET /pods
β βββ GET /deployments
β βββ GET /statefulsets
β βββ GET /services
βββ communications/
β βββ GET /
β βββ GET /{id}
β βββ GET /stats
βββ dependencies/
β βββ GET /graph
β βββ GET /map
β βββ GET /upstream/{workload_id}
β βββ GET /downstream/{workload_id}
βββ anomalies/
β βββ GET /
β βββ GET /{id}
β βββ PUT /{id}
β βββ POST /{id}/resolve
βββ changes/
β βββ GET /
β βββ GET /{id}
β βββ GET /timeline
βββ baselines/
β βββ GET /
β βββ POST /
β βββ GET /{id}
β βββ DELETE /{id}
βββ export/
β βββ GET /csv
β βββ GET /graph-json
β βββ POST /schedule
βββ import/
β βββ POST /csv
β βββ POST /graph-json
β βββ GET /jobs/{id}
βββ l7/
β βββ communications/
β β βββ GET / (L7 communication list)
β β βββ GET /stats (L7 statistics)
β β βββ GET /error-stats (L7 error breakdown)
β βββ dependencies/
β β βββ GET /graph (L7 dependency graph)
β β βββ GET /summary (L7 per-workload summary)
β β βββ GET /tree-summary (L7 tree-based dependencies)
β βββ events/
β βββ GET /http (HTTP flow events)
β βββ GET /grpc (gRPC flow events)
β βββ GET /dns (DNS flow events)
β βββ GET /stats (Cross-protocol stats)
β βββ GET /histogram (HTTP 5-min histogram)
βββ dependencies/
β βββ GET /unified-summary (L4+L7 merged dependencies)
βββ settings/
β βββ GET /beyla (Beyla L7 configuration)
β βββ PUT /beyla (Update Beyla configuration)
βββ clusters/
βββ GET /beyla-install-script (General Beyla install script)
βββ GET /{id}/beyla-install-script (Cluster-specific install)
βββ GET /{id}/beyla-upgrade-script (Beyla upgrade script)
```
### Frontend (React)
#### Technology Stack
- **Framework**: React 18+
- **UI Library**: Ant Design 5+
- **Graph Visualization**: Cytoscape.js
- **State Management**: Redux Toolkit + RTK Query
- **Routing**: React Router v6
- **HTTP Client**: Axios
- **Real-time**: Socket.IO Client
- **Charts**: Recharts / ApexCharts
- **Build Tool**: Vite
- **Language**: TypeScript
#### Component Structure
```
frontend/
βββ public/
β βββ index.html
βββ src/
β βββ index.tsx # Entry point
β βββ App.tsx # Root component
β βββ components/ # Reusable components
β β βββ Layout/
β β β βββ Header.tsx
β β β βββ Sidebar.tsx
β β β βββ Footer.tsx
β β βββ Graph/
β β β βββ CytoscapeGraph.tsx
β β β βββ GraphControls.tsx
β β β βββ GraphFilters.tsx
β β β βββ NodeDetailPanel.tsx
β β βββ Dashboard/
β β β βββ MetricCard.tsx
β β β βββ ChartCard.tsx
β β β βββ TimelineWidget.tsx
β β βββ Wizard/
β β β βββ AnalysisWizard.tsx
β β β βββ Step1Scope.tsx
β β β βββ Step2Gadgets.tsx
β β β βββ Step3Time.tsx
β β β βββ Step4Output.tsx
β β βββ Common/
β β βββ Table.tsx
β β βββ Modal.tsx
β β βββ Form.tsx
β βββ pages/ # Page components
β β βββ Login.tsx
β β βββ Home.tsx
β β βββ ClusterManagement.tsx
β β βββ AnalysisWizard.tsx
β β βββ LiveMap.tsx
β β βββ HistoricalMap.tsx
β β βββ ApplicationInventory.tsx
β β βββ AnomalyDetection.tsx
β β βββ ChangeDetection.tsx
β β βββ ImportExport.tsx
β β βββ PolicySimulation.tsx
β β βββ UserManagement.tsx
β β βββ Settings.tsx
β β βββ IntegrationHub.tsx
β βββ store/ # Redux store
β β βββ index.ts
β β βββ slices/
β β β βββ authSlice.ts
β β β βββ clusterSlice.ts
β β β βββ graphSlice.ts
β β β βββ analysisSlice.ts
β β βββ api/
β β βββ authApi.ts
β β βββ clusterApi.ts
β β βββ analysisApi.ts
β βββ hooks/ # Custom React hooks
β β βββ useAuth.ts
β β βββ useWebSocket.ts
β β βββ useGraph.ts
β β βββ useDebounce.ts
β βββ utils/ # Utility functions
β β βββ api.ts
β β βββ graph-utils.ts
β β βββ date-utils.ts
β β βββ format-utils.ts
β βββ types/ # TypeScript types
β β βββ user.types.ts
β β βββ cluster.types.ts
β β βββ graph.types.ts
β β βββ analysis.types.ts
β βββ styles/ # Global styles
β β βββ variables.less
β β βββ global.less
β β βββ theme.ts
β βββ constants/ # Constants
β βββ api-endpoints.ts
β βββ colors.ts
βββ package.json
βββ tsconfig.json
βββ vite.config.ts
```
### Database Schemas (High-Level)
#### PostgreSQL Schema
**Core Tables:**
- `users` - User accounts
- `roles` - RBAC roles
- `permissions` - Granular permissions
- `user_roles` - User-role mapping
- `clusters` - Kubernetes/OpenShift clusters
- `namespaces` - Namespace inventory
- `workloads` - Pod, Deployment, StatefulSet, Service
- `communications` - Communication records
- `analyses` - Analysis configurations
- `analysis_runs` - Analysis execution history
- `baselines` - Traffic baselines
- `anomalies` - Detected anomalies
- `change_events` - Change detection events (ACID operations)
- `change_workflow` - Workflow state (acknowledge, review, approve) π
- `analysis_runs` - Analysis run tracking π
- `risk_scores` - Risk scoring data
- `llm_configs` - LLM configuration
- `webhooks` - Webhook configurations
- `audit_logs` - Audit trail
- `import_jobs` - Import job tracking
- `export_jobs` - Export job tracking
#### Neo4j Schema
**Vertex Tags:**
- `Cluster` - Kubernetes cluster
- `Namespace` - Kubernetes namespace
- `Pod` - Kubernetes pod
- `Deployment` - Kubernetes deployment
- `StatefulSet` - Kubernetes statefulset
- `Service` - Kubernetes service
**Edge Types:**
- `COMMUNICATES_WITH` - Network communication
- `PART_OF` - Hierarchical relationship (pod β deployment)
- `EXPOSES` - Service exposure (service β deployment)
- `DEPENDS_ON` - Logical dependency
#### ClickHouse Schema
**Time-Series Tables:**
- `network_flows` - Raw network events
- `dns_queries` - DNS query logs
- `tcp_connections` - TCP connection events
- `request_metrics` - Request latency & frequency
- `process_events` - Process creation/termination
- `syscall_events` - System call tracking
- `file_access_events` - File access logs
- `workload_metadata` - Pod/workload discovery events π
- `change_events` - Infrastructure change events (run-based) π
---
## API Architecture
The HTTP API is organized under `/api/v1/` (see the endpoint tree under **Backend API (FastAPI)** above). **Authentication** supports both **JWT** (standard Bearer tokens) and **API keys** supplied via the **`X-API-Key`** header, so automation, agents, and CI/CD can authenticate without an interactive login flow.
**Integration** exposes dependency-oriented endpoints for CI/CD pipelines (tagged **Integration** in the OpenAPI spec), including:
| Area | Path (relative to `/api/v1`) |
|------|------------------------------|
| Summary (L4) | `GET /communications/dependencies/summary` |
| Streaming | `GET /communications/dependencies/stream` |
| Batch | `POST /communications/dependencies/batch` |
| Diff | `GET /communications/dependencies/diff` |
| Impact | `GET /communications/dependencies/impact` |
| Summary (L7) | `GET /l7/dependencies/summary` |
| Tree summary (L7) | `GET /l7/dependencies/tree-summary` |
Both the L4 and L7 summary endpoints accept the same identification surface (annotation key/value, label key/value, owner_name, pod_name) so the Integration Hub feeds a single form into either endpoint. The L7 path aliases `owner_name β workload_name` server-side. Filter values accept fnmatch globs (`*`, `?`, `[seq]`). When the L7 summary filter is active, matched workloads are returned with `is_matched=true` alongside their immediate neighbours (`is_matched=false`) so callers retain dependency context. v2.6.0+
When the operator picks an analysis with `analysis_level=both`, the Integration Hub fans the configured query out to **both** L4 and L7 endpoints in parallel (`Promise.allSettled`) and renders Network/Application tabs in the preview step plus an L4/L7 toggle in the snippet step. The L7 endpoints accept a single `analysis_id` per call, so multi-analysis selections target the first analysis on the L7 side and the full set on the L4 side.
These complement the core REST surface (graph, map, upstream/downstream) for programmatic analysis and integration scenarios.
---
## Deployment Architecture
### Kubernetes Namespace Organization
```
flowfish/ # Main application namespace
βββ frontend # Frontend deployment
βββ backend # Backend deployment
βββ postgresql # PostgreSQL StatefulSet
βββ clickhouse # ClickHouse StatefulSet
βββ neo4j-graphd # Neo4j graph service
βββ neo4j-metad # Neo4j meta service
βββ neo4j-storaged # Neo4j storage service
βββ redis # Redis deployment
flowfish-gadget/ # Inspektor Gadget namespace
βββ inspektor-gadget # DaemonSet
```
### Service Mesh Integration (Optional)
Flowfish can integrate with service meshes such as Istio or Linkerd:
```mermaid
graph LR
subgraph "Service Mesh Layer"
ENVOY1[Envoy Sidecar]
ENVOY2[Envoy Sidecar]
ENVOY3[Envoy Sidecar]
end
subgraph "Application Pods"
FE[Frontend] --> ENVOY1
BE[Backend] --> ENVOY2
DB[Database] --> ENVOY3
end
ENVOY1 --> ENVOY2
ENVOY2 --> ENVOY3
subgraph "Control Plane"
ISTIOD[Istio Control Plane]
end
ISTIOD -.->|Config| ENVOY1
ISTIOD -.->|Config| ENVOY2
ISTIOD -.->|Config| ENVOY3
ENVOY1 -.->|Telemetry| FLOWFISH[Flowfish Backend]
ENVOY2 -.->|Telemetry| FLOWFISH
ENVOY3 -.->|Telemetry| FLOWFISH
```
**Benefits:**
- Enhanced observability (L7 metrics)
- mTLS enforcement
- Traffic management
- Circuit breaking
- Canary deployments
### High Availability
**Frontend:**
- 2+ replicas
- HPA (CPU > 70%)
- Anti-affinity rules (spread across nodes)
**Backend:**
- 3+ replicas
- HPA (CPU > 70%, Memory > 80%)
- Anti-affinity rules
- Graceful shutdown (30s drain)
**PostgreSQL:**
- Master + Replica (Patroni/Stolon)
- Auto-failover
- Streaming replication
**ClickHouse:**
- 3+ nodes (distributed tables)
- Replication factor: 2
- ZooKeeper for coordination
**Neo4j:**
- 2 graphd (stateless, load balanced)
- 2 metad (HA with Raft)
- 3 storaged (distributed storage, Raft)
**Redis:**
- Sentinel for HA
- 1 master + 2 replicas
- Auto-failover
---
## Security Architecture
### Network Policies
```yaml
# Default deny all ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: flowfish
spec:
podSelector: {}
policyTypes:
- Ingress
# Allow frontend -> backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: flowfish
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8000
# Allow backend -> databases
# (similar rules for PostgreSQL, ClickHouse, Neo4j, Redis)
```
### Pod Security
```yaml
apiVersion: v1
kind: Pod
metadata:
name: backend
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: backend
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
```
### Secrets Management
- Kubernetes Secrets (encrypted at rest)
- External Secrets Operator (AWS Secrets Manager, Vault)
- Environment variable injection
- Volume mounts for sensitive files
---
## Monitoring and Observability
### Metrics (Prometheus)
**Application Metrics:**
- HTTP request rate, latency, errors (RED method)
- Graph query performance
- LLM API call duration
- WebSocket connections
- Background job durations
**Infrastructure Metrics:**
- CPU, memory, disk usage
- Pod restarts
- Network throughput
- Database connection pool
### Logging (ELK/Loki)
**Structured Logging:**
```json
{
"timestamp": "2024-01-15T10:30:45Z",
"level": "INFO",
"service": "backend",
"component": "analysis_service",
"trace_id": "abc123",
"user_id": "user-456",
"message": "Analysis started",
"analysis_id": "analysis-789",
"cluster_id": "cluster-prod"
}
```
### Tracing (Jaeger/Tempo)
- Distributed tracing across services
- OpenTelemetry instrumentation
- Span context propagation
- Trace sampling (10%)
### Alerting (Alertmanager)
**Critical Alerts:**
- Service down (any component)
- Database replication lag > 10s
- Disk usage > 85%
- API error rate > 5%
- LLM API failures > 10/min
**Warning Alerts:**
- High latency (p95 > 500ms)
- Memory usage > 80%
- Slow queries (> 5s)
- WebSocket connection drops
---
## Cluster Connectivity Architecture (December 2025 Update)
### ClusterConnectionManager
The backend uses a central `ClusterConnectionManager` service to access Kubernetes clusters.
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ClusterConnectionManager β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Features: β
β β
Connection pooling (per-cluster cache) β
β β
Automatic connection type detection (in-cluster/remote) β
β β
Credential management with Fernet encryption β
β β
Background health monitoring (circuit breaker) β
β β
Unified API β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββ΄ββββββββββββββββ
βΌ βΌ
ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
β InClusterConnection β β RemoteTokenConnection β
β (gRPC to cluster-mgr) β β (Direct K8s API) β
ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
```
### Connection Types
| Type | Use Case | Backend Implementation |
|------|----------|----------------------|
| **in-cluster** | Flowfish in the same cluster | gRPC β cluster-manager pod |
| **token** | Remote cluster (ServiceAccount) | httpx β K8s API Server |
| **kubeconfig** | Remote cluster (kubeconfig file) | kubernetes-client β K8s API |
### Key Files
```
backend/services/
βββ cluster_connection_manager.py # Unified manager singleton
βββ connections/
β βββ base.py # Abstract ClusterConnection
β βββ in_cluster.py # InClusterConnection
β βββ remote_token.py # RemoteTokenConnection
βββ health/
β βββ cluster_health_monitor.py # Background health checks
βββ cluster_cache_service.py # Redis cache (uses manager)
```
### Multi-Cluster Analysis Support
Flowfish can run analyses across multiple clusters:
- **Analysis ID Format**:
- Single cluster: `{analysis_id}`
- Multi-cluster: `{analysis_id}-{cluster_id}`
- **Data Isolation**: Each clusterβs data is kept separate
- **Unified View**: The frontend merges data from all clusters
---
**Version**: 2.0.0
**Last Updated**: January 2026
**Status**: Implementation Documentation
**Architecture**: Hybrid Change Detection (PostgreSQL + ClickHouse)