Files
fuzzforge_ai/backend
2025-09-30 12:10:47 +02:00
..
2025-09-29 21:26:41 +02:00
2025-09-29 21:26:41 +02:00
2025-09-29 21:26:41 +02:00
2025-09-29 21:26:41 +02:00
2025-09-29 21:26:41 +02:00
2025-09-29 21:26:41 +02:00

FuzzForge Backend

A stateless API server for security testing workflow orchestration using Prefect. This system dynamically discovers workflows, executes them in isolated Docker containers with volume mounting, and returns findings in SARIF format.

Architecture Overview

Core Components

  1. Workflow Discovery System: Automatically discovers workflows at startup
  2. Module System: Reusable components (scanner, analyzer, reporter) with a common interface
  3. Prefect Integration: Handles container orchestration, workflow execution, and monitoring
  4. Volume Mounting: Secure file access with configurable permissions (ro/rw)
  5. SARIF Output: Standardized security findings format

Key Features

  • Stateless: No persistent data, fully scalable
  • Generic: No hardcoded workflows, automatic discovery
  • Isolated: Each workflow runs in its own Docker container
  • Extensible: Easy to add new workflows and modules
  • Secure: Read-only volume mounts by default, path validation
  • Observable: Comprehensive logging and status tracking

Quick Start

Prerequisites

  • Docker and Docker Compose
  • Python 3.11+
  • UV package manager
  • Prefect server running (via docker-compose.yaml)

Installation

  1. Start Prefect infrastructure:
docker-compose up -d
  1. Run the backend (uses UV internally):
cd backend
PREFECT_API_URL="http://localhost:4200/api" PREFECT_RESULTS_PERSIST_BY_DEFAULT="true" uv run uvicorn src.main:app --reload --port 8000

API Endpoints

Workflows

  • GET /workflows - List all discovered workflows
  • GET /workflows/{name}/metadata - Get workflow metadata and parameters
  • POST /workflows/{name}/submit - Submit a workflow for execution
  • GET /workflows/{name}/parameters - Get workflow parameter schema

Runs

  • GET /runs/{run_id}/status - Get run status
  • GET /runs/{run_id}/findings - Get SARIF findings from completed run
  • GET /workflows/{name}/findings/{run_id} - Alternative findings endpoint

Metadata

  • GET /workflows/metadata/schema - Get metadata.yaml schema

Workflow Structure

Each workflow must have:

toolbox/workflows/{workflow_name}/
 workflow.py       # Prefect flow definition
 metadata.yaml     # Mandatory metadata (parameters, version, etc.)
 Dockerfile        # Optional custom container definition
 requirements.txt  # Optional Python dependencies

Example metadata.yaml

name: security_assessment
version: "1.0.0"
description: "Comprehensive security analysis workflow"
author: "FuzzForge Team"
category: "comprehensive"
tags:
  - "security"
  - "analysis"
  - "comprehensive"

supported_volume_modes:
  - "ro"
  - "rw"

requirements:
  tools:
    - "file_scanner"
    - "security_analyzer"
    - "sarif_reporter"
  resources:
    memory: "512Mi"
    cpu: "500m"
    timeout: 1800

has_docker: true

parameters:
  type: object
  properties:
    target_path:
      type: string
      default: "/workspace"
      description: "Path to analyze"
    volume_mode:
      type: string
      enum: ["ro", "rw"]
      default: "ro"
      description: "Volume mount mode"
    scanner_config:
      type: object
      description: "Scanner configuration"
      properties:
        max_file_size:
          type: integer
          description: "Maximum file size to scan (bytes)"

output_schema:
  type: object
  properties:
    sarif:
      type: object
      description: "SARIF-formatted security findings"
    summary:
      type: object
      description: "Scan execution summary"

Metadata Field Descriptions

  • name: Workflow identifier (must match directory name)
  • version: Semantic version (x.y.z format)
  • description: Human-readable description of the workflow
  • author: Workflow author/maintainer
  • category: Workflow category (comprehensive, specialized, fuzzing, focused)
  • tags: Array of descriptive tags for categorization
  • requirements.tools: Required security tools that the workflow uses
  • requirements.resources: Resource requirements enforced at runtime:
    • memory: Memory limit (e.g., "512Mi", "1Gi")
    • cpu: CPU limit (e.g., "500m" for 0.5 cores, "1" for 1 core)
    • timeout: Maximum execution time in seconds
  • parameters: JSON Schema object defining workflow parameters
  • output_schema: Expected output format (typically SARIF)

Resource Requirements Enforcement

FuzzForge automatically enforces resource requirements defined in workflow metadata:

  1. Deployment: Resource requirements are set as defaults when workflows are deployed
  2. Execution: During workflow submission, resources are applied to Docker containers
  3. User Override: Users can override workflow defaults by providing custom resource limits

Example API call with resource override:

curl -X POST "http://localhost:8000/workflows/security_assessment/submit" \
  -H "Content-Type: application/json" \
  -d '{
    "target_path": "/tmp/project",
    "volume_mode": "ro",
    "resource_limits": {
      "memory_limit": "1Gi",
      "cpu_limit": "1"
    }
  }'

Resource precedence: User limits > Workflow requirements > System defaults

Module Development

Modules implement the BaseModule interface:

from src.toolbox.modules.base import BaseModule, ModuleMetadata, ModuleResult

class MyModule(BaseModule):
    def get_metadata(self) -> ModuleMetadata:
        return ModuleMetadata(
            name="my_module",
            version="1.0.0",
            description="Module description",
            category="scanner",
            ...
        )

    async def execute(self, config: Dict, workspace: Path) -> ModuleResult:
        # Module logic here
        findings = [...]
        return self.create_result(findings=findings)

    def validate_config(self, config: Dict) -> bool:
        # Validate configuration
        return True

Submitting a Workflow

curl -X POST "http://localhost:8000/workflows/security_assessment/submit" \
  -H "Content-Type: application/json" \
  -d '{
    "target_path": "/home/user/project",
    "volume_mode": "ro",
    "parameters": {
      "scanner_config": {"patterns": ["*.py"]},
      "analyzer_config": {"check_secrets": true}
    }
  }'

Getting Findings

curl "http://localhost:8000/runs/{run_id}/findings"

Returns SARIF-formatted findings:

{
  "workflow": "security_assessment",
  "run_id": "abc-123",
  "sarif": {
    "version": "2.1.0",
    "runs": [{
      "tool": {...},
      "results": [...]
    }]
  }
}

Security Considerations

  1. Volume Mounting: Only allowed directories can be mounted
  2. Read-Only Default: Volumes mounted as read-only unless explicitly set
  3. Container Isolation: Each workflow runs in an isolated container
  4. Resource Limits: Can set CPU/memory limits via Prefect
  5. Network Isolation: Containers use bridge networking

Development

Adding a New Workflow

  1. Create directory: toolbox/workflows/my_workflow/
  2. Add workflow.py with a Prefect flow
  3. Add mandatory metadata.yaml
  4. Restart the backend - workflow is auto-discovered

Adding a New Module

  1. Create module in toolbox/modules/{category}/
  2. Implement BaseModule interface
  3. Use in workflows via import

Testing

# Run unit tests
pytest tests/unit/

# Run integration tests
pytest tests/integration/

License

MIT