System Architecture Overview
Architecture at a Glance
flow8 is a modular, distributed workflow automation platform designed for enterprise IT, security, and business process automation. The system separates concerns into layers: HTTP routing (Gorgany framework), business logic (services), data persistence (MongoDB), and pluggable runtime capabilities (component system).
High-Level Architecture Diagram
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ CLIENTS ββ Browser (UI) β REST API β WebSocket β MCP Agent βββββββββββββ¬βββββββββββββββ¬ββββββββββββββ¬βββββββββββββββ¬ββββββββββββ β β β β ββββββββββββββββ΄ββββββββββββββ΄βββββββββββββββ΄ββββββββββββ β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β HTTP Server (Gorgany Framework) β β Port 4454 (HTTP) β Port 4445 (MCP Server) β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β β βββββββββββββ΄ββββ¬βββββββββ΄βββββββββ¬ββββ΄ββββββββββ β β β β βββββΌβββββββββ ββββΌβββββββββββ ββββΌβββββββββ ββββΌβββββββββββ β HTTP Routesβ β Middleware β β WebSocket β β MCP Tools β β β β (Auth, CORS) β β Handler β β Execution β βββββ¬βββββββββ ββββ¬βββββββββββ ββββ¬βββββββββ ββββ¬βββββββββββ β β β β ββββββββββββββββ΄ββββββββββββββββββ΄ββββββββββββββ΄βββββββββββ β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β Service Layer (70+ Domain Services) β β Flow β Play β Layer β AI β Scheduler β β β Auth β Audit β Config β ... β ββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β βββββββββββββββββΌββββββββββββββββ β β β βββββββΌββββββ ββββββΌβββββββ ββββΌβββββββββββββ β MongoDB β β Component β β Background β β β β Registry β β Jobs (Cron, β β 43+ β β β β Cleanup) β β Collectionsβ β Storage β β β β β β AI β β β ββββββββββββββ β Database β βββββββββββββββββ β Providers β β Custom β ββββββββββββββ β βββββββββββββββββ΄βββββββββββββββββ β β βββββββΌβββββββ βββββββββββββββββ ββββΌβββββββββββ β External β β AWS S3, β β Channels β β Services β β Google Cloud β β 7701-7799 β β β β Microsoft β β (Async β β OAuth2 β β Graph, etc. β β Execution) β β Providers β β β β β βββββββββββββββ βββββββββββββββββ βββββββββββββββGorgany Framework
flow8 uses Gorgany (github.com/osbits/gorgany), a custom HTTP framework built on Goβs standard library. Gorgany provides:
- Routing: Type-safe path and query parameter binding
- Middleware pipeline: Request/response interception for auth, CORS, logging
- Provider/DI system: Dependency injection via struct tags (
container:"inject") - Error handling: Structured error responses with HTTP status codes
- CORS support: Configurable allowed origins, credentials, methods
flow8 registers all controllers and middleware via the provider pattern in pkg/provider/, and the Gorgany app is bootstrapped in server.go.
Provider & Dependency Injection
flow8 uses Gorganyβs provider system for inversion of control:
type MyService struct { FlowService *service.FlowService `container:"inject"` Storage component.StorageComponent `container:"inject"` Logger *zerolog.Logger `container:"inject"` DBClient *mongo.Client `container:"inject"`}Services are registered in pkg/provider/ and resolved at startup. This approach:
- Decouples dependencies from concrete implementations
- Enables testing via mock injection
- Centralizes configuration management
- Supports late-binding of component implementations
Key providers:
ProvideLogger()β zerolog instanceProvideDBClient()β MongoDB connectionProvideComponents()β named runtime capabilitiesProvideServices()β 70+ domain services
Component System
The component system is a critical abstraction layer that allows swappable implementations of runtime capabilities without code changes. Components are named, configurable, and selected at execution time.
Component Kinds
| Kind | Purpose | Examples |
|---|---|---|
storage | File and artifact persistence | Local filesystem, AWS S3, Google Cloud Storage |
ai | AI model providers | OpenAI, Anthropic Claude, Mistral, Ollama |
db | SQL database connectivity | PostgreSQL, MySQL (for workflow execution) |
request | HTTP client for external APIs | HTTP with retries, TLS validation |
console | Execution logging and debugging | Console output, structured logs |
Configuration
Components are stored in the component_configs MongoDB collection with structure:
{ "_id": "ObjectID", "name": "default-openai", "kind": "ai", "company_id": "...", "config": { "provider": "openai", "api_key": "[encrypted]", "model": "gpt-4", "temperature": 0.7 }, "is_default": true, "created_at": "...", "updated_at": "..."}Default vs Named Components
- Default component: One per kind per installation. Selected if no override is specified.
- Named component: Explicitly referenced by name in a flow or layer.
- Per-layer override: A flowlet can override its AI provider via
ComponentConfigIdsmap.
Example: A flowlet that uses a specific Mistral configuration:
{ "component_config_ids": { "ai": "mistral-production" }}This decouples flow definitions from provider credentials and enables:
- Zero-code provider switching: Change AI provider by updating component config
- Multi-tenancy isolation: Each company has its own default components
- Cost optimization: Route expensive operations to cheaper providers
- Gradual migration: Test new providers on subset of flows before full rollout
MongoDB Data Model
flow8 uses MongoDB as the primary data store with 43+ collections organized by domain:
Core Flow Entities
flows(DBFlow) β Flow definitions, metadata, version historyflowlets(DBFlowlet) β Individual steps in a flow with module referencesplays(DBPlay) β Individual execution instances with full state trackingplay_layers(DBPlayLayer) β Module execution records within a play
Configuration & Integration
companiesβ Multi-tenancy rootusersβ User accounts with encrypted credentialscomponent_configsβ Named runtime capabilitiesdb_links(DBLink) β Encrypted OAuth2 and API key credentialssystem_configβ Global settings and overrides
Operational
audit_logsβ Comprehensive audit trail (every request, CRUD, auth event)flows_allβ Retention-managed archivekv_storesβ Per-execution key-value state (scoped: global, flow, flow_group)retention_policiesβ Automated cleanup rules
Metadata
modules(cached) β 135+ built-in module catalogtemplatesβ Pre-built flow templatesflow_groupsβ Grouping and organizationtagsβ Custom metadata and categorization
Multi-tenancy is enforced at the query level: every read operation filters by company_id, and all mutations include company_id in writes.
Startup Sequence
flow8 initializes through a carefully ordered bootstrap process:
- Load environment variables β Read
.envfile viagodotenv - Initialize logging β Configure zerolog, set up audit logger with field sanitization
- Parse configuration β Load
config/config.ymlwith Viper (supports${VAR}substitution) - Connect to MongoDB β Establish primary database connection with retry logic
- Initialize components β Load component registry, resolve default AI/storage/db providers
- Register services β Inject 70+ domain services via provider system
- Setup Gorgany app β Register HTTP routes, middleware, WebSocket handlers, MCP server
- Start HTTP listener β Begin accepting requests on port 4454 (configurable via
SERVER_PORT)
Background jobs are spawned after HTTP startup:
- Scheduler β Cron-based flow execution (gorhill/cronexpr)
- Retention cleanup β Every 2 minutes, batch delete aged entries
- Audit filter cache β Every 3 minutes, refresh cached audit query filters
- TTL cache cleanup β Every 1 minute, evict expired test cases and modules
Port Layout
| Port | Service | Protocol | Purpose |
|---|---|---|---|
| 4454 | flow8 API & UI | HTTP/WebSocket | Main application (configurable via SERVER_PORT) |
| 4445 | MCP Server | HTTP | Model Context Protocol (JWT-authenticated) |
| 7701β7799 | Channel Ports | WebSocket/TCP | Async execution channels (100 concurrent per instance, range scales with instance count) |
For multi-instance deployments, each instance reserves a block of channel ports. For example:
- Instance 1: 7701β7799
- Instance 2: 7800β7899
- Instance 3: 7900β7999
Multi-Tenancy Architecture
Every flow8 entity includes a company_id field, and all database queries are automatically scoped to the authenticated userβs company. This ensures:
- Isolation: Data from different organizations never mixes
- Performance: Indexed queries filter by company first
- Simplicity: No complex access control lists at the data layer
Users can belong to multiple companies, and the session context determines which companyβs data is accessible in each request.
Key Design Principles
- Separation of Concerns: HTTP routing, business logic, and data persistence are clearly layered
- Pluggability: Components, modules, and external integrations are loosely coupled
- Observability: Comprehensive audit logging and zerolog structured logging throughout
- Security by Default: Field-level encryption, RBAC, multi-tenancy at the query layer
- Scalability: Stateless application layer, channel-based async execution, in-memory caching
- Developer Experience: Reflection-based module discovery, provider-based DI, clear package organization