nFlow Runtime
Workflow execution engine for nFlow. This project executes workflows created in the nFlow visual designer, providing a secure environment with resource limits and sandboxing.
π Installation
go get github.com/arturoeanton/nflow-runtime
π Requirements
- Go 1.19 or higher
- PostgreSQL or SQLite3
- Redis (optional, for sessions)
- Configuration in
config.toml
π― Features
- Secure Execution: JavaScript sandboxing with configurable resource limits
- High Performance: 3,396 RPS with compute-intensive JavaScript workflows (1M+ requests, 0% errors)
- Thread-Safe: Race condition-free architecture using Repository Pattern
- Extensible: Plugin system for custom functionality
- Detailed Logging: Structured logging system with verbose mode (-v)
- Complete Monitoring: Prometheus metrics and health checks
- Advanced Debugging: Debug endpoints with authentication
- Optimized: VM pool, multi-level caching and highly optimized code
- Rate Limiting: IP-based rate limiting with configurable backends
- Security Analysis: Static analysis of JavaScript before execution
- Automatic Encryption: Detection and encryption of sensitive data
- Log Sanitization: Automatic prevention of sensitive data exposure in logs
π§ Configuration
config.toml
[database_nflow]
driver = "postgres"
dsn = "user=postgres dbname=nflow sslmode=disable"
[redis]
host = "localhost:6379"
password = ""
[vm_pool]
# VM pool for high performance
max_size = 200 # Maximum VMs in pool (increased for 4x performance)
preload_size = 100 # VMs preloaded at startup
# Resource limits (security)
max_memory_mb = 128 # Maximum memory per VM
max_execution_seconds = 30 # Maximum execution time
max_operations = 10000000 # Maximum JS operations
# Sandbox settings
enable_filesystem = false # Filesystem access
enable_network = false # Network access
enable_process = false # Process access
[tracker]
enabled = false # Execution tracking (performance impact)
verbose_logging = false # Detailed tracker logs
[monitor]
enabled = true # Monitoring endpoints
health_check_path = "/health"
metrics_path = "/metrics"
[debug]
enabled = false # Debug endpoints (development only)
auth_token = "" # Authentication token
allowed_ips = "" # Allowed IPs (e.g., "192.168.1.0/24")
[mail]
enabled = false
smtp_host = "smtp.gmail.com"
smtp_port = 587
[rate_limit]
enabled = false # IP-based rate limiting
ip_rate_limit = 100 # Requests per IP per window
ip_window_minutes = 1 # Time window in minutes
[security]
# Static JavaScript analysis
enable_static_analysis = false # Detect dangerous patterns before execution
block_on_high_severity = true # Block scripts with severe issues
# Sensitive data encryption
enable_encryption = false # Auto-encrypt sensitive data
encryption_key = "" # 32-byte key for AES-256
encrypt_sensitive_data = true # Detect and encrypt emails, SSN, API keys, etc.
# Log sanitization
enable_log_sanitization = false # Mask sensitive data in logs
log_masking_char = "*" # Character for masking
log_show_type = true # Show masked data type
πββοΈ Basic Usage
As Standalone Server
# Normal mode
./nflow-runtime
# Verbose mode (detailed logging)
./nflow-runtime -v
Server will be available at http://localhost:8080
As Library
import (
"github.com/arturoeanton/nflow-runtime/engine"
"github.com/arturoeanton/nflow-runtime/process"
)
func main() {
// Initialize configuration
configRepo := engine.GetConfigRepository()
config := engine.ConfigWorkspace{
// ... configuration
}
configRepo.SetConfig(config)
// Initialize database
db, err := engine.GetDB()
if err != nil {
log.Fatal(err)
}
engine.InitializePlaybookRepository(db)
// Initialize process manager
process.InitializeRepository()
// Create Echo server
e := echo.New()
e.Any("/*", run)
e.Start(":8080")
}
π‘οΈ Security
Resource Limits
Each VM has configurable limits to prevent DoS attacks:
- Memory: 128MB by default
- Time: 30 seconds maximum
- Operations: 10M JavaScript operations
Sandboxing
JavaScript executes in a restricted environment:
- β
eval() blocked
- β
Function constructor blocked
- β Filesystem access disabled by default
- β Network access disabled by default
- β
Only whitelisted modules available
Static Analysis
Before execution, each script is analyzed to detect:
- Use of
eval() or new Function()
- Filesystem access (
require('fs'))
- Process spawning (
child_process)
- Potentially infinite loops
- Global scope modification
Data Protection
π Available Plugins
- goja: Main JavaScript engine
- mail: Email sending
- template: Template processing
- ianflow: AI integration (OpenAI, Gemini, Ollama)
- http: HTTP client for API calls
- db: Database operations
- babel: ES6+ code transpilation
π Architecture
nflow-runtime/
βββ engine/ # Main execution engine
β βββ engine.go # Workflow execution logic
β βββ vm_manager.go # VM pool for high performance
β βββ vm_limits.go # Resource limit management
β βββ vm_sandbox.go # Sandbox implementation
β βββ js_context_wrapper.go # Echo context wrapper for JS
β βββ config_repository.go # Repository pattern for config
βββ process/ # Process management
β βββ process_repository.go # Thread-safe repository
βββ endpoints/ # API endpoints
β βββ debug_endpoints.go # Debug endpoints
β βββ monitor_endpoints.go # Health & metrics
βββ logger/ # Logging system
β βββ logger.go # Structured logger with levels
βββ security/ # Security module
β βββ analyzer/ # Static JavaScript analysis
β βββ encryption/ # AES-256 encryption service
β βββ interceptor/ # Sensitive data interceptor
β βββ sanitizer/ # Log sanitizer
β βββ security_middleware.go # Unified middleware
βββ syncsession/ # Optimized session management
βββ plugins/ # System plugins
βββ main.go # Server entry point
π§© Custom Steps
You can create your own node types:
type MyCustomStep struct{}
func (s *MyCustomStep) Run(
cc *model.Controller,
actor *model.Node,
c echo.Context,
vm *goja.Runtime,
connection_next string,
vars model.Vars,
currentProcess *process.Process,
payload goja.Value,
) (string, goja.Value, error) {
// Your implementation here
return nextNode, payload, nil
}
// Register the step
engine.RegisterStep("my-custom-step", &MyCustomStep{})
π Metrics and Monitoring
Monitoring Endpoints
- Health Check:
GET /health - System health status
- Prometheus Metrics:
GET /metrics - All metrics in Prometheus format
Available Metrics
nflow_requests_total: Total HTTP requests
nflow_workflows_total: Total workflows executed
nflow_processes_active: Active processes
nflow_db_connections_*: Database connection metrics
nflow_go_memory_*: Memory usage
nflow_cache_hits/misses: Cache statistics
Debug Endpoints (when enabled)
/debug/info: System information
/debug/config: Current configuration
/debug/processes: Active process list
/debug/cache/stats: Cache statistics
/debug/database/stats: Database metrics
See DEBUG_MONITORING.md for complete documentation.
π‘οΈ Rate Limiting
nFlow Runtime includes IP-based rate limiting to protect against abuse:
- Token bucket algorithm for flexible rate control
- Memory and Redis backends for different deployment scenarios
- Configurable exclusions for IPs and paths
- Detailed headers for client integration
See RATE_LIMITING.md for complete documentation.
nFlow Runtime has been optimized to handle heavy JavaScript workloads:
VM Pool
- Goja VM reuse through configurable pool
- Pre-loading of VMs at startup for immediate availability
- Intelligent management with 5-second wait timeout
- Detailed pool status metrics
Cache System
- Babel Cache: ES6 transformations in memory
- Program Cache: Pre-compiled JavaScript
- Auth.js Cache: Avoids repetitive file reads
JMeter Test Results
- Tested workflow: httpstart β js-JsonRender with 1000 mathematical calculations
- Demonstrated throughput: 3,396 req/s (~3.4 million calculations/second)
- Reliability: 1,007,399 requests processed with 0% errors
- Average latency: 860ms (includes JS compilation + 1000 operations)
- Response times: Minimum 25ms, maximum 2,488ms
- Standard deviation: 87.36ms (predictable behavior)
- Transfer capacity: 5,265.98 KB/s
π¨ Error Handling
Errors are handled consistently:
- HTTP 408: Resource limit exceeded
- HTTP 500: Internal server error
- HTTP 404: Workflow not found
π Project Status
- Maturity: 4.9/5 β (Production ready)
- Stability: STABLE β
- Security: EXCELLENT β
(Static Analysis + Encryption + Sanitization)
- Performance: 3,396 RPS with intensive JavaScript (0% errors) β
- Observability: COMPLETE β
(Health checks + Prometheus + Debug endpoints)
- Production Ready: 99% β
See STATUS.md for more details.
π Known Issues
See DEUDA.md for the complete technical debt list.
π€ Contributing
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature)
- Commit your changes (
git commit -m 'Add some AmazingFeature')
- Push to the branch (
git push origin feature/AmazingFeature)
- Open a Pull Request
π License
MIT - see LICENSE file for details.
π Acknowledgments
- Goja - JavaScript engine in Go
- Echo - Web framework
- nFlow - Visual workflow designer