OpenScan is an open-source security scanning and asset discovery platform. It continuously monitors your internet-facing assets β domains, subdomains, IPs, and ports β and alerts you when things change.
"Monitor your websites and servers in one place. Lock the doors before anyone gets in."
- Subdomain Discovery β Automatically discover subdomains and internet-facing assets using multiple tools
- Host Discovery β Ping sweeps and IP/CIDR range scanning to find live hosts
- HTTP Service Probing β Enrich discovered hosts with HTTP metadata (status codes, titles, headers, tech stack)
- Multi-Scanner Engine β Combines masscan (ultra-fast, all ports), rustscan (fast with service detection), and nmap (deep fingerprinting) for comprehensive coverage
- Smart Port Merging β Deduplicates and merges results from multiple scanners automatically
- Service Detection β Identifies running services, versions, and operating systems
- Scheduled Scanning β Configurable scan schedules (QUICK, STANDARD, THOROUGH) with automatic retries and failure escalation
- Servers Dashboard β Centralized view of all discovered servers with status filtering
- Device Detail β Per-device view with open ports, services, scan history, CVE vulnerabilities, and activity timeline
- Tagging & Organization β Organize assets by projects and tags
- CVE Enrichment β Automatically cross-references detected services with known CVEs
- Severity Scoring β CVSS-based severity classification (CRITICAL, HIGH, MEDIUM, LOW, INFO)
- Vulnerability Timeline β Track when vulnerabilities appear and get resolved
- Real-time Change Detection β Automatically detects new ports, closed ports, service drift, and CVE changes between scan runs
- Email Alerts β Rich HTML email notifications via Resend with categorized templates
- Telegram Alerts β Optional Telegram bot integration for instant notifications
- Suppression Windows β Configurable quiet periods to avoid alert fatigue
- Notification Preferences β Per-organization severity filtering for each channel
- Browser Rendering β Cloudflare Browser Rendering API captures live screenshots of web services
- R2 Storage β Screenshots stored in Cloudflare R2 for long-term retention
- IP Enrichment β Automatically detects cloud/hosting providers for discovered IPs (AWS, GCP, Azure, DigitalOcean, etc.)
- Multi-tenant β Organizations with member management and role-based access
- Onboarding Flow β Guided setup: create account β create project β asset discovery β notification configuration
- Project Isolation β Assets and scans scoped to projects within organizations
OpenScan uses a distributed microservices architecture with durable workflow orchestration:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Cloudflare Workers β
β β
β βββββββββββββββ βββββββββββββββββ ββββββββββββββββββββββββ β
β β Web App β β Data Service β β Screenshot Worker β β
β β (TanStack β β (Notificationsβ β (Browser Rendering) β β
β β Start/React)β β Delivery) β β β β
β ββββββββ¬ββββββββ ββββββββ¬βββββββββ ββββββββββββ¬ββββββββββββ β
β β β β β
β β Cloudflare D1 (SQLite) β β
β β Cloudflare R2 (Screenshots) β β
βββββββββββΌβββββββββββββββββββΌβββββββββββββββββββββββββΌββββββββββββββ
β β β
β HTTP Postback (Universal Format) β
β β β
βΌ βΌ βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Restate Worker β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββββ β
β β Discovery β β Port Scanner β β Scan Executor β β
β β Service β β (masscan/ β β (Scheduled Scanning) β β
β β β β rustscan) β β β β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββββ β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββββ β
β β HTTPx β β Hosting β β Device Scanner β β
β β Service β β Enrichment β β (Virtual Objects) β β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββββ β
β Durable Workflow Orchestration β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Layer | Technology |
|---|---|
| Frontend | TanStack Start (React 19) + TanStack Router + TanStack Query |
| Styling | Tailwind CSS v4 + Radix UI Primitives |
| Workflow Orchestration | Restate β Durable execution engine |
| Edge Compute | Cloudflare Workers |
| Database | Cloudflare D1 (Serverless SQLite) |
| ORM | Drizzle ORM β Type-safe SQL |
| Auth | Better Auth |
| RPC | tRPC v11 β End-to-end type-safe APIs |
| Resend + React Email templates | |
| Validation | Zod β Runtime type validation |
| Package Manager | pnpm workspaces |
| Language | TypeScript (strict mode) |
Restate workers communicate with the web app via HTTP callbacks β a simple, robust pattern:
- Web app invokes a Restate workflow via HTTP API
- Restate worker executes the durable workflow (scanning, discovery, etc.)
- Worker sends results back via HTTP POST to the web app (the "postback")
- Web app processes and persists the results
This decouples the scanning pipeline from the application layer, making each component independently deployable and testable.
openscan/
βββ apps/
β βββ web/ # π Main web application
β β βββ src/
β β β βββ routes/ # TanStack file-based routing
β β β βββ features/ # Feature modules (servers, scans, discovery, etc.)
β β β βββ components/ # Reusable UI components (Radix + Tailwind)
β β β βββ queries/ # TanStack Query + tRPC hooks
β β β βββ modals/ # Modal dialogs
β β β βββ server/ # Server functions & postback handlers
β β β βββ lib/ # Utilities, auth client, tRPC setup
β β βββ public/ # Static assets + _routes.json
β β βββ worker/ # Cloudflare Worker entry
β β βββ wrangler.jsonc # Cloudflare deployment config
β β
β βββ restate-worker/ # π Durable workflow orchestration
β β βββ src/
β β β βββ discovery-service.ts # Subdomain/host discovery
β β β βββ port-scanner.ts # Port scanning orchestrator
β β β βββ device-scanner-service.ts# Scheduled scanning (Virtual Objects)
β β β βββ scan-executor-service.ts # Scan execution logic
β β β βββ httpx-service.ts # HTTP service probing
β β β βββ hosting-enrichment-service.ts # Cloud provider detection
β β β βββ scanners/ # masscan, rustscan implementations
β β β βββ xml-parser/ # Nmap XML result parsing
β β β βββ postback.ts # Universal postback helper
β β βββ src/__tests__/ # Integration & unit tests
β β
β βββ data-service/ # π¬ Notification delivery worker
β β βββ src/
β β β βββ index.ts # Queue consumer + Hono API
β β βββ emails/ # React Email templates
β β βββ wrangler.jsonc
β β
β βββ screenshot-worker/ # πΈ Browser screenshot worker
β βββ src/
β β βββ handlers/ # Capture, HTTPx, health endpoints
β β βββ services/ # Browser rendering, storage, postback
β β βββ types/ # Environment & type definitions
β βββ wrangler.jsonc
β
βββ packages/
β βββ data-ops/ # ποΈ Database operations (single source of truth)
β β βββ src/
β β β βββ schema/ # Drizzle schema definitions
β β β βββ queries/ # Database queries (devices, scans, notifications, etc.)
β β β βββ auth/ # Better Auth server setup
β β β βββ database/ # D1 connection & initialization
β β βββ migrations/ # SQL migrations
β β
β βββ contracts/ # π Shared types, schemas, and contracts
β β βββ postbacks/ # Universal postback payload schemas
β β βββ scanners/ # Scanner configuration types
β β βββ artifacts/ # Scan artifact types
β β
β βββ validation/ # β
Shared Zod validation schemas
β βββ constants/ # π’ Shared constants & utilities
β βββ config/ # βοΈ Shared configuration
β βββ logger/ # π Shared logging utilities
β
βββ docs/ # π Documentation
β βββ architecture/ # System architecture docs
β βββ features/ # Feature-specific documentation
β β βββ notifications/ # Notification delivery system
β β βββ scans/ # Scan architecture
β β βββ discovery/ # Discovery workflow
β β βββ ...
β βββ practices/ # Development guidelines
β
βββ scripts/ # Utility scripts
βββ pnpm-workspace.yaml
βββ tsconfig.base.json
βββ README.md
- Node.js 22.x (required β the project uses
.nvmrc) - pnpm 10+
- Wrangler CLI β
npm install -g wrangler - Restate β Local or Cloud deployment (docs)
- Cloudflare account β For D1, Workers, R2, and Queues
# 1. Clone the repository
git clone https://github.com/your-org/openscan.git
cd openscan
# 2. Use the correct Node.js version
nvm use
# 3. Install dependencies and build shared packages
pnpm run setup
# 4. Set up environment variables
cp apps/web/.env.example apps/web/.env
cp apps/restate-worker/.env.example apps/restate-worker/.env
# 5. Run database migrations
cd packages/data-ops
pnpm drizzle-kit push
cd ../..pnpm run dev:web
# Starts at http://localhost:13000pnpm run dev:worker
# Starts Restate endpoint on port 9080cd apps/data-service
pnpm run devcd apps/screenshot-worker
pnpm run devpnpm run deploy:webpnpm run deploy:data-servicepnpm run deploy:screenshot-workerRefer to apps/restate-worker/README.md for detailed deployment instructions.
OpenScan includes a comprehensive notification pipeline:
Port Scan Complete β Change Detection β Create Notifications
β
Filter by Org Severity Preferences
β
Enqueue to Cloudflare Queue
β
Data Service Consumes Queue
β
Send Emails via Resend + Telegram
Supported Event Types:
- π΄ New critical/high-priority ports discovered
- π‘ New CVEs detected on existing services
- π΅ Service drift (version changes, product changes)
- βͺ Closed/downtime ports
- π’ Server promoted from candidate to verified
- π Batch scan summaries
See docs/features/notifications/operations.md for full details.
The docs/ directory contains comprehensive documentation:
| Topic | Location |
|---|---|
| Architecture Overview | docs/architecture/ |
| Postback System | docs/architecture/backend/postback-architecture.md |
| Notification Delivery | docs/features/notifications/ |
| Scan Architecture | docs/features/scans/ |
| Discovery Workflows | docs/features/discovery/ |
| Scheduled Scanning | docs/features/schedules/ |
| Service Detection | docs/architecture/service-detection/ |
| Optimistic UI Patterns | docs/optimistic-ui.md |
| Development Best Practices | docs/practices/ |
Single source of truth for all database queries. The golden rule: never import database internals directly in apps β always use exported query functions.
// β
Correct
import { getDevicesForTenant, createDevicesInProject } from "@repo/data-ops";
// β Wrong
import { getDb } from "@repo/data-ops/database/setup";
import { devices } from "@repo/data-ops/schema";Domain types that serve as the single source of truth across UI, workers, and data-ops. Includes postback payload schemas with Zod runtime validation.
- Cloudflare D1 (SQLite) with Drizzle ORM
- Schema-first approach with Zod validation at all layers
- CI/CD: Type-level tests catch schema drift across packages
# Run all tests
pnpm -r test
# Restate worker tests (integration + unit)
cd apps/restate-worker
pnpm run test:run
# Data service tests
cd apps/data-service
pnpm run test
# Type checking
pnpm -r typecheckWe use beads for dependency-aware issue tracking. All issues are prefixed with sec- (e.g., sec-42).
bd list -s open # View open issues
bd ready # See unblocked work
bd show sec-42 # View issue detailsISC
