ScanopyScanopy

Architecture

Technical overview of Scanopy's system design and components.

Technical overview of Scanopy's system design, components, and data flows.

Components

Server

Purpose: Central hub for data storage, API, and web UI serving

Responsibilities:

  • Store network discovery data in PostgreSQL
  • Serve REST API for daemons and UI
  • Generate topology visualizations
  • Manage user authentication and sessions
  • Orchestrate scheduled discoveries
  • Handle organization and user management
  • Provide real-time updates via Server-Sent Events

Implementation:

  • Language: Rust
  • Framework: Axum (async web framework)
  • Database: PostgreSQL 17 with sqlx
  • Authentication: tower-sessions + OIDC (openidconnect crate)
  • Frontend bundling: Integrated Svelte build in Docker image

Runs as: Docker container (recommended) or standalone binary

Daemon

Purpose: Distributed discovery agent that scans networks and reports findings

Responsibilities:

  • Scan IPv4 addresses on configured subnets
  • Detect open TCP ports
  • Identify services via pattern matching
  • Connect to Docker socket for container discovery
  • Report host interfaces and capabilities
  • Send heartbeats to maintain connection
  • Execute scheduled discovery tasks

Implementation:

  • Language: Rust
  • Network scanning: Custom async TCP scanner with tokio
  • Docker API: bollard crate for Docker socket communication
  • Service detection: Pattern matching engine with 200+ definitions
  • Configuration: JSON file + environment variables + CLI args

Runs as: Docker container (Linux only) or standalone binary (all platforms)

UI

Purpose: Web-based interface for viewing and managing network data

Responsibilities:

  • Display interactive topology diagrams
  • Provide CRUD interfaces for all entities
  • Monitor discovery sessions in real-time
  • Manage users and organizations
  • Configure discovery schedules
  • Export topology visualizations

Implementation:

  • Framework: Svelte 5 + SvelteKit
  • State management: Svelte stores with derived reactivity
  • Visualization: @xyflow/svelte for topology rendering
  • Forms: svelte-forms with custom validation
  • Styling: Tailwind CSS
  • Real-time: Native EventSource for SSE

Runs as: Static files served by the server (bundled in Docker image)

Data Flows

DaemonPoll Mode

DaemonPoll is the default mode. The daemon initiates all connections to the server, making it ideal for daemons behind NAT or firewalls.

Initialization (DaemonPoll)

Runtime Polling (DaemonPoll)

Discovery Flow (DaemonPoll)

ServerPoll Mode

ServerPoll mode is for DMZ deployments where the daemon cannot make outbound connections. The server initiates all connections to the daemon. Requires the daemon to be network-accessible from the server.

Initialization (ServerPoll)

Runtime Polling (ServerPoll)

Discovery Flow (ServerPoll)

Mode Comparison

AspectDaemonPollServerPoll
Connection directionDaemon → ServerServer → Daemon
SetupDaemon self-registersAdmin provisions in UI
Firewall requirementsOutbound only from daemonInbound to daemon (port 60073)
Best forNAT/firewall environmentsDMZ deployments
Entity handlingImmediate processingBuffered with confirmation

Discovery Pipeline

Network Scan

Docker Discovery


For implementation details, see the source code.

On this page