

| Manufacturer | Devices | Share |
|---|---|---|
| Loading… | ||
| Device | IP | Type | Manufacturer | Threat Level |
|---|---|---|---|---|
| Loading… | ||||
| Hop | Latency | Jitter | Packet Loss | Bandwidth | Status |
|---|
| Application | Round-Trip Latency | Worst Loss | Experience | Last Measured |
|---|
Click a framework to view how NetScout's monitoring maps to its controls. Status is derived live from your current monitoring posture.
| Control | Requirement | Mapped NetScout Evidence | Status |
|---|---|---|---|
| Loading… | |||
| Date / Time | User / Entity | Anomaly | Baseline Deviation | Risk | Status | Source | |
|---|---|---|---|---|---|---|---|
| Loading… | |||||||
| User | Source IP | Location | Devices / IPs | Baseline | Last Active | Risk | Source |
|---|---|---|---|---|---|---|---|
| Loading… | |||||||
Loading…
netscout.confLoading…
brew install python nmap
curl -L -o netscout-agent.zip https://…/agent.zip
unzip netscout-agent.zip
cd netscout/backend
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
netscout.conf in any text editor and paste the config snippet above into the [cloud] section.
netscout.conf, confirm the [cloud] section contains the correct gateway address:
gateway_url = https://netscout.incytes.net
PASTE_GATEWAY_URL_HERE, replace it with the value shown above. A wrong URL means the agent will push data to the wrong server and nothing will appear on your dashboard.sudo for packet capture (NIDS & ARP scanning):sudo .venv/bin/python main.py
cloud_push: heartbeat lines in the terminal.
winget install Python.Python.3.11
winget install Insecure.Nmap
Invoke-WebRequest -Uri https://…/agent.zip -OutFile agent.zip
Expand-Archive agent.zip -DestinationPath .
cd netscout\backend
python -m venv .venv
.venv\Scripts\pip install -r requirements.txt
netscout.conf in Notepad and paste the config snippet above into the [cloud] section.
netscout.conf, confirm the [cloud] section contains the correct gateway address:
gateway_url = https://netscout.incytes.net
PASTE_GATEWAY_URL_HERE, replace it with the value shown above. A wrong URL means the agent will push data to the wrong server and nothing will appear on your dashboard..venv\Scripts\python main.py
cloud_push: heartbeat lines in the terminal.
brew install python nmap
Loading…
netscout.conf and paste the [cloud] snippet from the Connect Agent page.sudo .venv/bin/python main.py
winget install Python.Python.3.11Loading…
netscout.conf and paste the [cloud] snippet from the Connect Agent page..venv\Scripts\python main.py
Integrate with Open Threat Exchange (OTX) to enrich the platform with real-time threat intelligence: IOC lookups, active threat pulses, MITRE ATT&CK mapping, CVE enrichment, and automatic correlation of scanned network devices against known-bad indicators. Get a free API key at — https://otx.alienvault.com/
NetScout is a network intelligence and security-monitoring platform. It runs a Python FastAPI backend on your server or workstation and exposes this web interface for real-time visibility into every device on your LAN.
Scans are powered by nmap for port discovery and OS fingerprinting, combined with ARP/ICMP probes for fast host enumeration. A live WebSocket feed pushes device updates, scan progress, and intrusion alerts to every connected browser tab instantly — no page refresh needed.
The scanner runs a multi-phase discovery pipeline against the target CIDR:
| Phase | Method | What it finds |
|---|---|---|
| Host Discovery | ARP sweep + ICMP ping | All IP addresses with a live host |
| Port Scan | nmap TCP SYN scan (top 1 000 ports) | Open ports, service names |
| Service Detection | nmap version probe (-sV) | Product names, versions, banners |
| OS Fingerprint | nmap OS detection (-O) | Probable OS and version |
| MAC Lookup | OUI database | Manufacturer / vendor name |
| Hostname | Reverse DNS | Friendly device name |
Filters — Use the filter bar to show Active (currently responding), Passive (seen before but silent now), or Risky (high/critical vulnerability score) devices. The free-text search matches IP, hostname, vendor, and MAC address. Changing any filter or sort resets to page 1 automatically.
Pagination — Device cards are shown 9 per page with ‹ / › navigation and numbered page buttons. Use the arrows or page numbers to move between pages.
Editing devices — Click a device card to open its detail sheet. You can override the auto-detected hostname, vendor, and device type. Edits persist across scans.
Tap Assess on any device to launch a deep scan. The engine probes all ports (not just the top 1 000), detects software versions, and cross-references them against a local CVE database.
Each finding includes:
Assessments are saved to disk (assessments.json) and survive server restarts. Risk levels are reflected immediately on device cards without re-scanning.
The Network Intrusion Detection System passively sniffs all IP traffic on your interface using Scapy. It runs entirely agent-less — nothing is installed on monitored devices.
Detection rules (60-second sliding window):
| Alert Type | Trigger | Severity |
|---|---|---|
| Port Scan | ≥ 10 distinct destination ports from one source | HIGH |
| SYN Flood | ≥ 100 SYN-only packets from one source | CRITICAL |
| Brute Force | ≥ 5 connections to SSH, RDP, FTP, Telnet, etc. from one source | HIGH |
| ICMP Flood | ≥ 50 ICMP packets from one source | HIGH |
| Suspicious Port | Connection to known C2 / malware ports (4444, 1337, SMB, etc.) | MEDIUM |
The NIDS auto-starts when the backend launches and is restarted automatically by a 60-second watchdog if it stops unexpectedly. Event history is stored in nids_events.json (last 500 events) and hourly/daily buckets for the charts.
Filter bar — The Recent Alerts table includes a live filter bar with the following controls:
Pagination — Alerts are displayed 20 per page with ‹ / › navigation and numbered page buttons. Applying a filter resets to page 1.
Agent-less Host-based Intrusion Detection — no software is installed on target machines. NetScout connects over SSH (Linux/macOS), WinRM (Windows), or SNMP and runs read-only inspection commands to detect misconfigurations and signs of compromise.
What it checks:
To run a scan — go to the Devices page, click 🔑 on a host, enter SSH (or WinRM/SNMP) credentials, and click Run Authenticated Scan. Results appear immediately in the HIDS page and are saved to disk.
Dashboard — KPIs & Charts
Persistent event log — Every scan's findings are appended to hids_events.json (up to 2 000 events). Re-scanning the same host adds new entries rather than overwriting old ones, preserving the full history across server restarts.
The Forensic Analysis page (left navigation, below Host Intrusion) provides deep per-device inspection without requiring root access or installing agents. It runs five complementary scan modes and shows results in a device-grid view. Results persist across server restarts.
| Scan Mode | What it does |
|---|---|
| Full | Runs all four modes below in sequence — the most complete picture of a device. |
| Traffic | Reads the local connection table (netstat/ss/lsof) for active connections to/from the device, performs a brief tshark capture if pcap access is available, and surfaces existing NIDS events for that IP. No root required. |
| Endpoint | TCP-connect port scan (nmap -sT, no raw sockets), HTTP banner grabs, SSL certificate inspection, and SNMP community probe. |
| IoT / UAC | Compares the device's open ports against expected-port baselines for its type (Router, Camera, IoT Device, Printer, Server, Phone). Flags dangerous ports — Telnet, FTP, unencrypted MQTT, RDP, VNC, SMB, Redis, MongoDB — with severity ratings. |
| Dead-box SSH | Connects over SSH using saved device credentials and runs read-only forensic commands on the remote host. Credentials are held in memory only — never written to disk. |
KPI strip — six clickable chips at the top filter the device grid: Total Devices · Scanned · Running · High+ Risk · Total Findings · Isolated.
Controls
Filter bar — narrow the grid by free-text (IP, hostname, vendor), status (All / Unscanned / Active / Done / Risky / Isolated), or severity (None / Medium / High / Critical).
Each device card shows overall risk level, finding count, scan mode, duration, and an expandable list of findings. Every finding includes a severity badge, title, description, evidence lines, and a remediation recommendation.
The Events page (left navigation, after HIDS) merges NIDS alerts and HIDS findings into a single chronological log. It is the definitive view of all security activity across both detection engines.
KPI strip at the top shows:
Filter bar — seven independent filter controls:
| Filter | Values |
|---|---|
| IP | Free-text match against source IP |
| Search | Free-text match against title, detail, and category |
| Source | All Sources / NIDS / HIDS |
| Category | Grouped dropdown — NIDS categories (Port Scan, SYN Flood, …) and HIDS categories (ssh_config, firewall, kernel, …) |
| Severity | All Severities / Critical / High / Medium / Low |
| Type | All Types / Internal / External (based on RFC-1918 IP ranges) |
| Time | All Time / Last 1 h / 6 h / 24 h / 7 days |
Event table — columns: Time · Source · Severity · Category · IP · Type · Title · Detail. Source is badged NIDS (purple) or HIDS (green). External IPs are highlighted in amber for quick identification.
Pagination — 16 events per page with ‹ / › navigation. Filter changes reset to page 1. A result count shows the number of matching events.
Data sources — NIDS events are fetched from /api/nids/events (up to 500). HIDS events are fetched from /api/hids/events (up to 2 000, the persistent accumulated log). The page auto-refreshes when a new authenticated scan completes.
The Topology view is an animated canvas-based network map showing your LAN as a hierarchy: Internet (top) → Router/Gateway → group cards fanning out left and right. Edges to cards that contain devices show flowing animated dots.
Group cards — Right column: Active · Open Ports · No Risk. Left column: High Risk · Passive · Critical Risk. The five stat chips in the header (Devices, Active, Risky, Passive, Open Ports) are clickable and jump to the Devices page with the matching filter pre-applied.
Node colours:
Hover any node to see its IP, hostname, vendor, OS, risk level, and open port count. The canvas re-renders automatically after each scan.
The Security Posture page (left navigation, above Dashboard) maps every detected security event — from both NIDS and HIDS — onto two industry frameworks. A range selector (1d / 3d / 7d / 14d / 30d) stays in sync with all other pages.
⛓ Kill Chain Taxonomy — a stage flow strip (Reconnaissance → Delivery → Exploitation → Installation → Command & Control → Actions on Objectives) plus a bar chart of alert volume per stage. Click any stage to open the matching events.
🛡 MITRE ATT&CK® Framework Mapping — a grid of 10 enterprise tactic cells (5 per row) listing the relevant ATT&CK technique IDs and event counts. Each technique carries a badge:
Tactics with detected events are highlighted and clickable — they open the Events page filtered to that tactic's detections.
The User Experience page measures the real network path — hop by hop — from the server to internet destinations and external SaaS applications. It uses traceroute-style probing to detect where latency, jitter, or packet loss is introduced, and scores the end-to-end experience 0–100.
Slice controls — three buttons at the top let you pivot the view by Device, Application, or User. Pick a slice, then choose a specific entity from the dropdown. The range selector (1d / 3d / 7d / 14d / 30d) is synced with all other pages.
Network Path Analysis — a hop-flow diagram showing each router along the path. The hop with the largest latency increase is flagged as the bottleneck. The Hop Telemetry table below it shows per-hop latency, jitter, packet loss, bandwidth, and a Good / Average / Poor / Bottleneck status for each hop.
User Experience Over Time — a line chart of the experience score over the selected window, colour-coded:
External SaaS Applications — a table showing the current path experience to 10 cloud services (Microsoft 365, Google Workspace, Salesforce, Slack, Zoom, Dropbox, Adobe Creative Cloud, ServiceNow, Workday, HubSpot), probed automatically every 30 minutes. Click ↻ Measure now to trigger an on-demand probe.
The Device Dashboard (left nav, below Activity Dashboard) classifies every discovered device and visualises the fleet in two dimensions.
By Category — nested donut
A two-ring (sunburst) donut. The inner ring shows device categories (Phone, Laptop, PC, Tablet, Printer, Camera, IoT Device, Router, Server, Other). The outer ring breaks each category down by manufacturer, sharing the category's colour with graduated opacity. The hollow centre shows the live device total.
Tables (paginated, 10 rows/page)
The Reports page is a full audit trail of scan activity, organised across three tabs. Use the range selector (1d / 3d / 7d / 14d / 30d) to limit the view to a time window, and the search box on each tab to filter by IP or hostname.
| Tab | What it shows | KPIs |
|---|---|---|
| Vulnerability Assessments | One row per assessed device — worst CVE severity, finding counts, last scan time. Rows link to the device detail sheet. | Total Scanned · Critical · High · Medium · Clean |
| Authenticated Scans | One row per HIDS-scanned host — finding severity breakdown, scan timestamp. Rows link to the device detail sheet. | Total Scanned · Critical · High · Medium · Clean |
| User Activity | Login and logout events — user, source IP, method (password / Google), and timestamp. | Total Events · Logins · Logouts |
All three tabs support sortable columns (click any header to sort; click again to reverse) and pagination. KPI cards are clickable and act as quick filters — e.g. clicking High filters the table to devices with ≥ 3 findings.
NetScout integrates with the Open Threat Exchange (OTX) by AlienVault to enrich every scan with real-world, crowdsourced threat data. When configured by an admin, every discovered device IP is automatically cross-referenced against the global OTX threat database — flagging known malicious hosts, attaching active IOCs, and surfacing the threat actors and malware families relevant to your network.
KPI strip — the top of the page shows live counts from your subscribed OTX pulse corpus:
| KPI | What it measures |
|---|---|
| Subscribed Pulses | Total OTX threat pulses you follow — click to browse on OTX |
| IOC Matches | Number of scanned devices checked in the last correlation run |
| Active Pulses (30d) | Pulses updated in the last 30 days — a measure of feed freshness |
| Malware Families | Unique malware families tracked across all subscribed pulses |
| MITRE Techniques | Unique MITRE ATT&CK® technique IDs referenced across subscribed pulses — click to open attack.mitre.org |
Automatic correlation — no action needed
Correlation runs automatically in the background every time a network scan completes, a NIDS intrusion alert fires, or an authenticated HIDS assessment finishes. Results are broadcast over WebSocket instantly — the page updates without a refresh. You can also trigger a manual run at any time with the Correlate Now button in the Network Device Correlation card.
IOC Lookup — query OTX on demand for any indicator:
Threat Pulses — the Pulses card lists your subscribed OTX threat pulses. Each card shows the pulse name, author, TLP classification, tags, targeted industries and countries, MITRE ATT&CK technique IDs, malware family names, indicator count, and last-modified date. Use the modified since date filter to narrow to recently updated pulses.
Network Device Correlation — the Correlation card shows the most recent run results:
The Correlation History card below it shows the last 50 threat-positive runs (paginated, 5 per page) with timestamp, trigger source, and per-run threat/clean counts.
The Dashboard shows time-series charts for six network metrics. Use the range selector to switch between 24 h (hourly buckets) and 7 / 14 / 30 / 90-day (daily buckets) views.
| Metric | Description |
|---|---|
| Active Devices | Devices responding to ARP/ping at scan time |
| Passive Devices | Devices seen historically but not responding now |
| Risky Devices | Devices with a Critical or High vulnerability rating |
| Open Ports | Total exposed ports across all devices |
| Vulnerability Scans | Cumulative per-device assessments run |
| Auth Scans | Cumulative authenticated (SSH/WinRM) assessments run |
History is stored in history.json (daily) and history_hourly.json (hourly). Up to 90 days of daily data and 48 hours of hourly data are retained automatically.
NetScout is a network intelligence and security-monitoring platform. It runs a Python FastAPI backend on your server or workstation and exposes this web interface for real-time visibility into every device on your LAN.
Scans are powered by nmap for port discovery and OS fingerprinting, combined with ARP/ICMP probes for fast host enumeration. A live WebSocket feed pushes device updates, scan progress, and intrusion alerts to every connected browser tab instantly — no page refresh needed.
The scanner runs a multi-phase discovery pipeline against the target CIDR:
| Phase | Method | What it finds |
|---|---|---|
| Host Discovery | ARP sweep + ICMP ping | All IP addresses with a live host |
| Port Scan | nmap TCP SYN scan (top 1 000 ports) | Open ports, service names |
| Service Detection | nmap version probe (-sV) | Product names, versions, banners |
| OS Fingerprint | nmap OS detection (-O) | Probable OS and version |
| MAC Lookup | OUI database | Manufacturer / vendor name |
| Hostname | Reverse DNS | Friendly device name |
Filters — Use the filter bar to show Active (currently responding), Passive (seen before but silent now), or Risky (high/critical vulnerability score) devices. The free-text search matches IP, hostname, vendor, and MAC address. Changing any filter or sort resets to page 1 automatically.
Pagination — Device cards are shown 9 per page with ‹ / › navigation and numbered page buttons. Use the arrows or page numbers to move between pages.
Editing devices — Click a device card to open its detail sheet. You can override the auto-detected hostname, vendor, and device type. Edits persist across scans.
Tap Assess on any device to launch a deep scan. The engine probes all ports (not just the top 1 000), detects software versions, and cross-references them against a local CVE database.
Each finding includes:
Assessments are saved to disk (assessments.json) and survive server restarts. Risk levels are reflected immediately on device cards without re-scanning.
The Network Intrusion Detection System passively sniffs all IP traffic on your interface using Scapy. It runs entirely agent-less — nothing is installed on monitored devices.
Detection rules (60-second sliding window):
| Alert Type | Trigger | Severity |
|---|---|---|
| Port Scan | ≥ 10 distinct destination ports from one source | HIGH |
| SYN Flood | ≥ 100 SYN-only packets from one source | CRITICAL |
| Brute Force | ≥ 5 connections to SSH, RDP, FTP, Telnet, etc. from one source | HIGH |
| ICMP Flood | ≥ 50 ICMP packets from one source | HIGH |
| Suspicious Port | Connection to known C2 / malware ports (4444, 1337, SMB, etc.) | MEDIUM |
The NIDS auto-starts when the backend launches and is restarted automatically by a 60-second watchdog if it stops unexpectedly. Event history is stored in nids_events.json (last 500 events) and hourly/daily buckets for the charts.
Filter bar — The Recent Alerts table includes a live filter bar with the following controls:
Pagination — Alerts are displayed 20 per page with ‹ / › navigation and numbered page buttons. Applying a filter resets to page 1.
Agent-less Host-based Intrusion Detection — no software is installed on target machines. NetScout connects over SSH (Linux/macOS), WinRM (Windows), or SNMP and runs read-only inspection commands to detect misconfigurations and signs of compromise.
What it checks:
To run a scan — go to the Devices page, click 🔑 on a host, enter SSH (or WinRM/SNMP) credentials, and click Run Authenticated Scan. Results appear immediately in the HIDS page and are saved to disk.
Dashboard — KPIs & Charts
Persistent event log — Every scan's findings are appended to hids_events.json (up to 2 000 events). Re-scanning the same host adds new entries rather than overwriting old ones, preserving the full history across server restarts.
The Forensic Analysis page (left navigation, below Host Intrusion) provides deep per-device inspection without requiring root access or installing agents. It runs five complementary scan modes and displays results in a paginated device-grid view. Results persist across server restarts in backend/forensics_results.json.
| Scan Mode | What it does | Root needed |
|---|---|---|
| Full | Runs all four modes below in sequence — the most complete picture of a device. | No |
| Traffic | Reads local connection table (netstat/ss/lsof) for connections to/from the device, performs a brief tshark packet capture if pcap group access is available, and surfaces existing NIDS events for that IP. | No |
| Endpoint | TCP-connect port scan (nmap -sT, no raw sockets), HTTP banner grabs, SSL certificate inspection, and SNMP community probe. | No |
| IoT / UAC | Compares the device's open ports against expected-port baselines for its type (Router, Camera, IoT Device, Printer, Server, Phone). Flags dangerous ports — Telnet, FTP, unencrypted MQTT, RDP, VNC, SMB, Redis, MongoDB — with severity ratings. | No |
| Dead-box SSH | Connects over SSH using saved device credentials and runs read-only forensic commands on the remote host. Credentials follow the same in-memory-only policy as HIDS. | No |
IoT / UAC check catalogue — the following port-level checks are performed regardless of device type:
| Check | Port | Severity | Risk |
|---|---|---|---|
| Telnet open | 23 | CRITICAL | Credentials transmitted in cleartext |
| FTP open | 21 | HIGH | Unencrypted file transfer |
| SNMP v1/v2c | 161 | HIGH | Community strings brute-forceable |
| MQTT plain | 1883 | HIGH | Unencrypted MQTT broker |
| RDP exposed | 3389 | CRITICAL | High brute-force and RCE risk |
| VNC exposed | 5900 | CRITICAL | Remote desktop without strong auth |
| SMB exposed | 445 | CRITICAL | EternalBlue and ransomware vector |
| Redis plain | 6379 | CRITICAL | Unauthenticated access common |
| MongoDB plain | 27017 | CRITICAL | Often runs unauthenticated by default |
| JetDirect print | 9100 | HIGH | Can inject PostScript jobs |
| UPnP/SSDP | 1900 | MEDIUM | Network mapping & pivoting risk |
| RTSP exposed | 554 | MEDIUM | Live video stream may be accessible |
Scheduled forensics — in addition to on-demand scans, a full forensic sweep of all active devices runs automatically every 3 days at 01:00 local time. The next scheduled run is shown in the status bar at the top of the Forensic Analysis page. Schedule state is persisted in backend/forensic_schedule.json.
Device Isolation (admin-only) — admins can enable the Enable Isolation toggle in the toolbar. Once enabled, individual device cards show an Isolate button. Isolation works by ARP-poisoning (via Scapy) or by injecting a firewall block rule (pfctl on macOS, iptables on Linux). The device is never powered off — only its network path is severed. Isolation state is shown in the KPI strip and can be cleared per-device.
REST endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /api/forensics/{ip} | Fetch the latest forensic result for a device |
| POST | /api/forensics/{ip} | Start a forensic scan for one device |
| POST | /api/forensics/batch | Start forensic scans for multiple (or all) devices |
| POST | /api/forensics/stop | Cancel all running forensic scans |
| GET | /api/forensics/schedule | Return the next scheduled run time |
The Events page (left navigation, after HIDS) merges NIDS alerts and HIDS findings into a single chronological log. It is the definitive view of all security activity across both detection engines.
KPI strip at the top shows:
Filter bar — seven independent filter controls:
| Filter | Values |
|---|---|
| IP | Free-text match against source IP |
| Search | Free-text match against title, detail, and category |
| Source | All Sources / NIDS / HIDS |
| Category | Grouped dropdown — NIDS categories (Port Scan, SYN Flood, …) and HIDS categories (ssh_config, firewall, kernel, …) |
| Severity | All Severities / Critical / High / Medium / Low |
| Type | All Types / Internal / External (based on RFC-1918 IP ranges) |
| Time | All Time / Last 1 h / 6 h / 24 h / 7 days |
Event table — columns: Time · Source · Severity · Category · IP · Type · Title · Detail. Source is badged NIDS (purple) or HIDS (green). External IPs are highlighted in amber for quick identification.
Pagination — 16 events per page with ‹ / › navigation. Filter changes reset to page 1. A result count shows the number of matching events.
Data sources — NIDS events are fetched from /api/nids/events (up to 500). HIDS events are fetched from /api/hids/events (up to 2 000, the persistent accumulated log). The page auto-refreshes when a new authenticated scan completes.
The Topology view is an animated canvas-based network map that renders your LAN as a live hierarchy: Internet (top) → Router/Gateway → six group cards fanning out left and right.
Layout — group cards:
| Column | Cards (top → bottom) |
|---|---|
| Right | Active · Open Ports · No Risk |
| Left | High Risk · Passive · Critical Risk |
Animated edges — edges to cards that have devices show flowing animated dots. The dot speed and density reflect activity level.
Stat chips — the five chips at the top of the Topology header (Devices, Active, Risky, Passive, Open Ports) are clickable links. Clicking any chip navigates directly to the Devices page with the matching filter pre-applied.
Node colours:
Hover any node to see its IP, hostname, vendor, OS, risk level, and open port count. Clicking a group card navigates to the Devices page with the matching filter. The canvas re-renders automatically after each scan completes.
The Security Posture page (left navigation, above Dashboard) is a strategic security view that maps every detected security event — from both NIDS and HIDS — onto two industry frameworks. A range selector (1d / 3d / 7d / 14d / 30d) is fully synced with all other pages.
⛓ Kill Chain Taxonomy
A stage flow strip (Reconnaissance → Delivery → Exploitation → Installation → Command & Control → Actions on Objectives) followed by a horizontal bar chart showing alert volume per stage. NIDS categories map to stages as follows:
| Kill Chain Stage | Mapped detections |
|---|---|
| Reconnaissance | Port Scan, ICMP Flood |
| Delivery | SYN Flood |
| Exploitation | Brute Force |
| Installation | No direct sensor — shown dimmed |
| Command & Control | Suspicious Port |
| Actions on Objectives | Inferred / post-compromise — shown dimmed |
Clicking any stage card or bar navigates to the Events page filtered to that stage's categories.
🛡 MITRE ATT&CK® Framework Mapping
A grid of 10 enterprise tactic cells (5 per row) covering Reconnaissance, Initial Access, Credential Access, Defense Evasion, Persistence, Privilege Escalation, Discovery, Lateral Movement, Command & Control, and Impact. Each cell lists the relevant ATT&CK technique IDs (e.g. T1046 Network Service Scanning, T1110 Brute Force) with a count of matching events.
Tactics with detected events are highlighted with their tactic colour and are clickable — they navigate to the Events page filtered to the underlying NIDS categories.
The User Experience page (left navigation) measures the real network path — hop by hop — from the server to internet destinations and external SaaS applications. It uses traceroute-style probing to detect where latency, jitter, or packet loss is introduced, and scores the end-to-end experience 0–100.
Slice controls — three segmented buttons at the top let you pivot the view:
| Slice | Entity selector shows | What it measures |
|---|---|---|
| Device | Discovered devices on your LAN | Path from the server to that device's IP |
| Application | The 10 monitored SaaS apps | Path from the server to that app's hostname |
| User | NetScout user accounts | Path to the source IP of the user's last login |
Pick a slice, then choose a specific entity from the dropdown. The range selector (1d / 3d / 7d / 14d / 30d) and the ↺ Refresh button are fully synced with all other pages.
KPI strip — shows the current end-to-end latency, packet loss, jitter, and overall experience rating for the selected entity.
Network Path Analysis — a hop-flow diagram rendered from the latest traceroute probe. Each circle is a network hop (router or gateway); the hop with the largest latency increase is flagged as the bottleneck. Clicking ↻ Measure now on the External SaaS panel triggers an on-demand probe immediately.
Hop Telemetry — a table with one row per hop:
| Column | Description |
|---|---|
| Hop | Hop number and IP address (or * * * for non-responding hops) |
| Latency | Round-trip time to this hop in ms |
| Jitter | Variation in latency across probe samples |
| Packet Loss | % of probe packets that received no reply at this hop |
| Bandwidth | Estimated available bandwidth (where measurable) |
| Status | Good · Average · Poor · Bottleneck |
User Experience Over Time — a line chart of the experience score (0–100) over the selected time window. Each point is colour-coded:
External SaaS Applications — a table showing the current path experience to the 10 pre-configured cloud services, probed automatically every 30 minutes:
| Application | Measured host |
|---|---|
| Microsoft 365 | outlook.office365.com |
| Google Workspace | mail.google.com |
| Salesforce | login.salesforce.com |
| Slack | slack.com |
| Zoom | zoom.us |
| Dropbox | www.dropbox.com |
| Adobe Creative Cloud | www.adobe.com |
| ServiceNow | www.servicenow.com |
| Workday | www.workday.com |
| HubSpot | www.hubspot.com |
Each row in the table shows round-trip latency, worst packet loss, an experience badge, and the time of the last probe. Click ↻ Measure now to trigger an immediate probe of all 10 apps.
UEBA learns how each user and entity normally behaves, then flags deviations and scores them by risk. It follows a three-stage model, shown as cards at the top of the page:
| Stage | What it does |
|---|---|
| ① Baseline Creation | Analyses login history (and, where available, traffic) to learn each user's typical login times, source IPs, and locations. |
| ② Anomaly Detection | Compares live activity against the baseline in real time — off-hours logins, never-before-seen source IPs, external (public-IP) logins, and failed-login bursts. |
| ③ Risk Scoring | Scores each deviation 0–100 so minor events are ignored while high-risk, correlated activity is flagged: 0–39 ignored · 40–74 watch · 75–100 flagged. |
Data sources — real vs demo
UEBA derives real signals from data NetScout already collects:
Illustrative demo rows are shown alongside the real data so the page reads as a populated dashboard. Every row carries a Source badge — ● Real or ● Demo — and both tables have a source filter (All / Real only / Demo only).
🔎 Live Anomaly Feed — each detected deviation with its local Date/Time, user/entity, the anomaly, baseline deviation, a 0–100 risk score, a disposition (🚩 Flagged / 👁 Watch / ✓ Ignored), and a Source badge. Click Details to expand a drawer showing the learned baseline, observed behaviour, contributing signals, and a recommended action.
👥 Users Monitored — the roster built from real login profiles: user, last source IP, location (Internal LAN vs External public), distinct device/IP count, baseline status (✓ Established / ◷ Learning %), last-active time, and live risk. The top Users Monitored KPI card links straight to this table.
Both tables support, exactly like the Reports page:
The Compliance page maps NetScout's monitoring — device discovery, NIDS, HIDS, user activity, and vulnerability assessments — to the control requirements of the major frameworks, and produces an audit-ready report. Each framework's readiness is computed live from your current posture, not hard-coded.
| Framework | Applies to |
|---|---|
| GDPR | Any business or site handling EU residents' personal data |
| HIPAA | Practices / clinics handling protected health information (PHI) |
| PCI DSS | Anyone storing, processing or transmitting cardholder data |
| ISO 27001 | Any organisation seeking a certifiable ISMS baseline |
Framework cards — each shows a live readiness ring (percentage of applicable controls met) plus a count of met / manual / total controls. Click a card to load its control mapping below.
Control mapping table — for the selected framework, every control row shows:
Live posture sources — statuses flip automatically as you enable monitoring:
| Evidence | Derived from |
|---|---|
| Device Discovery | Discovered device inventory (/api/devices) |
| NIDS | Network IDS running state (/api/nids/status) |
| HIDS | Host IDS findings (/api/hids/events) |
| User Activity | Login / access activity log (/api/reports) |
| Vuln Assessment | Completed vulnerability assessments |
⤓ Generate Report — produces a clean, print-ready report covering all four frameworks (readiness %, full control tables, monitoring posture, timestamp) in a new window that auto-opens the print dialog, so it can be saved directly as PDF.
The Reports page (left navigation, below Events) is the audit trail for all assessment and user-access activity. It has three tabs, each with its own KPI strip and a searchable, paginated table. The range selector (1d / 3d / 7d / 14d / 30d) is shared across all tabs.
| Tab | KPIs | Table |
|---|---|---|
| Vulnerability Assessments | Total Scanned · Critical · High · Medium · Clean | One row per assessed device — IP, hostname, risk level, vulnerability count, last assessment time. Search by IP or hostname. Click Total Scanned or a tier KPI to filter the table to that risk tier. |
| Authenticated Scans | Total Scanned · Critical · High · Medium · Clean | One row per HIDS-scanned host — IP, hostname, finding count by severity, last scan time. Search by IP or hostname. Click a tier KPI to filter. |
| User Activity | Total Events · Logins · Logouts | Complete login/logout event log — timestamp, user, source IP, event type. Search by user or IP. Click the Logins or Logouts KPI to filter to that event type. Up to 1 000 events retained. |
The Device Dashboard (left nav, below Activity Dashboard) classifies every discovered device and visualises the fleet in two dimensions.
By Category — nested donut
A two-ring (sunburst) donut. The inner ring is the device category (Phone, Laptop, PC, Tablet, Printer, Camera, IoT Device, Router, Server, Other) — the same customizable device_type you set per device on the Device Inventory page. The outer ring breaks each category down by manufacturer (e.g. 54 IoT devices → Ring, Tapo, eWeLink …), sharing the category's hue with graduated opacity. The hollow centre shows the live device total.
Tables (paginated, 10 rows/page)
The Dashboard shows time-series charts for six network metrics. Use the range selector to switch between 24 h (hourly buckets) and 7 / 14 / 30 / 90-day (daily buckets) views.
| Metric | Description |
|---|---|
| Active Devices | Devices responding to ARP/ping at scan time |
| Passive Devices | Devices seen historically but not responding now |
| Risky Devices | Devices with a Critical or High vulnerability rating |
| Open Ports | Total exposed ports across all devices |
| Vulnerability Scans | Cumulative per-device assessments run |
| Auth Scans | Cumulative authenticated (SSH/WinRM) assessments run |
History is stored in history.json (daily) and history_hourly.json (hourly). Up to 90 days of daily data and 48 hours of hourly data are retained automatically.
NetScout uses session token authentication. Passwords are hashed with bcrypt (never stored in plaintext). Sessions expire after 24 hours.
The backend is managed by netscout-daemon.py in the backend/ directory:
The server listens on 0.0.0.0:8765 by default. Change host and port in backend/netscout.conf. The web interface is served at http://<host>:8765/ui/.
Admin Console (in-app) — the Admin page (left nav, admin-only) provides:
Server History (last 30 days) — a paginated table (10 rows/page) recording every server lifecycle event, captured from the actual process lifecycle (not just API calls) so daemon restarts, watchdog restarts and system shutdowns are all logged:
| Event | When it's recorded |
|---|---|
| 🟢 Start | Every server startup (lifespan) |
| 🔴 Stop | Every graceful shutdown — daemon stop/restart, watchdog, API stop, or OS shutdown (SIGTERM) |
| 🔄 Restart | In-app Restart button / API restart (os.execv) |
| ⚠️ Crash | Detected on next start when the previous run ended without a clean stop (SIGKILL / power loss) |
The Duration column shows the interval ending at each event — ▲ up while the server was running (start → stop) or ▼ down while it was offline (stop → start). History persists in server_history.json (last 500 events).
NetScout integrates with the Open Threat Exchange (OTX) by AlienVault to enrich every scan with real-world, crowdsourced threat data. When configured, every discovered device IP is automatically cross-referenced against the global OTX threat database — flagging known malicious hosts, attaching active IOCs, and surfacing the threat actors and malware families currently exploiting software vulnerabilities on your network.
Configuring the OTX API key
Threat Intelligence tab
The Threat Intelligence page (left nav, shield icon — visible to all authenticated users once OTX is configured) is the primary view. A KPI strip at the top shows live counts from your subscribed OTX pulse corpus:
| KPI | What it measures |
|---|---|
| Subscribed Pulses | Total OTX threat pulses you follow — links to OTX browse page |
| Devices Correlated | Number of scanned devices checked in the last correlation run |
| Recent Pulses | Pulses updated in the last 30 days (active threat feed freshness) |
| Malware Families | Unique malware families tracked across all subscribed pulses |
| MITRE Techniques | Unique MITRE ATT&CK® technique IDs referenced across all subscribed pulses — links to attack.mitre.org |
Automatic correlation — no action needed
When OTX is configured, correlation runs automatically in the background every time one of these events occurs:
| Trigger | When it fires |
|---|---|
| scan_complete | After every network scan (manual or scheduled) |
| nids_event | After each NIDS intrusion alert |
| auth_scan | After an authenticated (HIDS) assessment completes |
Results are broadcast instantly over WebSocket — the Threat Intelligence page updates without a page refresh. Only runs that found at least one threat are saved to the correlation history.
How correlation works
For each scanned device IP the engine queries OTX in two steps:
Each match record includes: IP · hostname · vendor · pulse count · reputation score · country · ASN · malware sample count · pulse names (threat actor context).
IOC Lookup
The IOC Lookup card on the Threat Intelligence page lets you query OTX for any indicator on demand. Supported types:
Each lookup queries six OTX sections simultaneously: general, reputation, geo, malware, url_list, and passive_dns. CVEs found by the Vulnerability Assessment engine can also be enriched individually — click the CVE ID on any assessment result to open the OTX enrichment panel.
Threat Pulses
The Pulses card lists your subscribed OTX threat pulses — the crowdsourced intelligence feeds published by researchers and the security community. Each pulse card shows:
Use the modified since date filter to narrow to recently updated pulses. The full pulse corpus is cached for 5 minutes server-side to avoid rate-limiting during repeated searches.
Network Device Correlation
The Network Correlation card shows the most recent correlation run and lets you trigger a manual correlation at any time with the Correlate Now button. Results show:
The Correlation History card shows the last 50 threat-positive runs (paginated, 5 per page) with timestamp, trigger source, and per-run threat/clean counts.
Integration Validation Report
Auto-Correlation Triggers — fires without user action
Correlation Pipeline — per scanned device IP
REST Endpoints — 9 total
| Method | Path | Purpose |
|---|---|---|
| GET | /api/threat/status | OTX configured check |
| GET | /api/threat/ioc/{type}/{value} | Multi-section IOC lookup (6 sections) |
| GET | /api/threat/pulses | Subscribed pulses (paginated, date-filterable) |
| GET | /api/threat/pulses/all | Full pulse set for search (5-min cache) |
| GET | /api/threat/pulse-stats | Malware families + MITRE techniques + recent count |
| GET | /api/threat/correlate | Manual network correlation against current scan |
| GET | /api/threat/last-correlation | Most recent correlation result (threats or clean) |
| GET | /api/threat/correlation-history | Paginated threat-positive history (last 50) |
| GET | /api/threat/cve/{cve_id} | CVE enrichment from OTX |
Run python3 netscout-daemon.py setup once to install the platform auto-start. It detects your OS and installs the appropriate service:
| Platform | Mechanism | Starts at |
|---|---|---|
| macOS | User LaunchAgent (~/Library/LaunchAgents/) | Login (FileVault-compatible) |
| Linux (systemd) | User systemd service | Login / session start |
| Linux (no systemd) | cron @reboot + watchdog | Boot |
| Windows | Task Scheduler (ONSTART) | System startup |
On macOS all daemon files (logs, PID file) are stored in ~/Library/NetScout/ to avoid macOS TCC (privacy sandbox) restrictions on ~/Downloads. The server itself runs as root (via sudo) for NIDS raw-packet capture.
The watchdog loop (run by launchd/systemd) checks server health via TCP every 60 seconds and restarts it automatically if it stops.
By default NetScout is only accessible on your local network (http://<ip>:8765/ui/). Cloudflare Tunnel exposes it securely on the internet at a custom domain — with HTTPS, DDoS protection, and no open firewall ports — for free.
Recommended URL pattern: https://netscout.yourdomain.com
| File | Location (macOS auto-start) | Contents |
|---|---|---|
| server.log | ~/Library/NetScout/logs/ | uvicorn / FastAPI output (server stdout) |
| daemon.log | ~/Library/NetScout/logs/ | Daemon watchdog events (start/stop/restart) |
| daemon-launchd.log | ~/Library/NetScout/logs/ | launchd stdout/stderr for the daemon process |
| netscout.pid | ~/Library/NetScout/logs/ | PID of the running server process |
| devices.json | backend/ | Persisted device list (survives restarts) |
| assessments.json | backend/ | Vulnerability assessment results |
| auth_assessments.json | backend/ | Latest authenticated (HIDS) assessment per host |
| forensics_results.json | backend/ | Forensic analysis results — one entry per device, persisted across restarts |
| forensic_schedule.json | backend/ | Next scheduled forensic sweep time (full scan, all active devices, every 3 days at 01:00) |
| nids_events.json | backend/ | Last 500 NIDS alerts (persisted across restarts) |
| hids_events.json | backend/ | Accumulated HIDS findings — up to 2 000 events across all scans and sessions |
| hids_history_hourly.json | backend/ | HIDS hourly metric buckets (7-day rolling) |
| hids_history_daily.json | backend/ | HIDS daily metric buckets (30-day rolling) |
| history.json | backend/ | Daily network metric snapshots (90-day rolling) |
| history_hourly.json | backend/ | Hourly network metric snapshots (48-hour rolling) |
| users.json | backend/ | User accounts (bcrypt hashes) |
| activity_log.json | backend/ | Login/logout event log — user, source IP, event type, timestamp (last 1 000 events) |
| overrides.json | backend/ | User-edited device names/types |
| speedtest_history.json | backend/ | Internet speed test results (download, upload, latency, jitter, packet loss) |
| server_history.json | backend/ | Server lifecycle events — start, stop, restart, crash (last 500) |
| auth_scan_history.json | backend/ | Authenticated (HIDS) scan history log |
| correlation_history.json | backend/ | OTX threat-positive correlation runs — last 50, newest first |
| last_correlation.json | backend/ | Most recent OTX correlation result (threats or clean) |
Server logs rotate automatically at 10 MB (keeping 5 archives) when running via the daemon. Adjust log_max_mb and log_keep in netscout.conf.
| Symptom | Likely cause | Fix |
|---|---|---|
| Browser shows "Offline" | Backend not running or wrong host/port | Run python3 netscout-daemon.py status. Click ⚙ to verify host:port. |
| Server stopped after restart | Auto-start not installed, or TCC/permission error (macOS) | Run python3 netscout-daemon.py setup to reinstall. Check daemon-launchd.log. |
| NIDS error: "Permission denied: could not open /dev/bpf0 … running Scapy as root" | Server is running as a non-root user — raw packet capture needs root | Set run_as_root = true, then provide root via sudo_password in netscout.conf or a NOPASSWD sudoers rule at /etc/sudoers.d/netscout for the exact <python> main.py command, then restart. The rule must match the precise launch command (it's command-specific). |
| Restart prints "Server process exited immediately (code 1)" but starts later | Stale: cached-sudo probe mismatch (fixed) | Run python3 netscout-daemon.py setup to refresh the launchd copy of the daemon, then restart. The daemon now attempts the real elevated launch and falls back cleanly instead of erroring. |
| Scan finds 0 devices | Wrong CIDR, VPN active, or firewall blocking ARP | Verify subnet with ifconfig/ipconfig. Disable VPN. Try a specific host (/32). |
| Vulnerability assessment hangs | Device firewalled or nmap not installed | Install nmap: brew install nmap / apt install nmap. Check firewall rules on target. |
| Google Sign-In button missing | Google Client ID not configured | Set NETSCOUT_GOOGLE_CLIENT_ID env var or write the ID to backend/.google_client_id. |
| Dashboard charts are empty | No scans yet today | Run a manual scan. The scheduler fires automatically every 4 hours at :00 (00:00, 04:00, 08:00, …). |
| HIDS / Events page shows no historical data | hids_events.json not yet created (server ran old code) | Restart the server. On startup the backfill creates hids_events.json from current assessments automatically. |
| HIDS KPIs differ from Events page counts | Both pages now use the same source; mismatch may indicate stale cache | Click ↺ Refresh on the Events page and switch away/back to HIDS to force a reload. |
| Cloudflare Tunnel URL shows error after Mac sleep/restart | Tunnel service not running or NetScout daemon stopped | Check: sudo launchctl list | grep cloudflare and python3 netscout-daemon.py status. Re-run sudo cloudflared service install if needed. |
| Topology page blank after login | Canvas not yet initialised or scan has no data | Hard-refresh the browser (Cmd+Shift+R) to clear any cached JS. Run a manual scan to populate device data. |
| Threat Intelligence tab shows "OTX API Key Not Configured" | No API key has been saved yet | Go to Admin → scroll to the OTX card → paste your key and click Save, then Test. Register for a free key at otx.alienvault.com. |
| OTX key test returns "Invalid OTX API key" | Key is malformed, expired, or copied with extra whitespace | Re-copy the key from OTX → My Profile → API Integration. Make sure there are no leading/trailing spaces. Keys are 64 hex characters. |
| Correlation runs but shows 0 threats for all devices | LAN IPs (RFC-1918 ranges) have no OTX hit — expected | Private IP addresses (192.168.x.x, 10.x.x.x, 172.16–31.x.x) are almost never in OTX. Threats appear when an internet-routable IP on your network (e.g. a cloud server, VPN endpoint, or rogue device) matches a pulse. |
| Threat Intelligence page KPIs show "—" after key is saved | Pulse stats not yet fetched or OTX rate-limited | Navigate away and back to the Threat Intelligence tab to trigger a fresh fetch. If the issue persists, check server.log for OTX API errors. The pulse cache refreshes every 5 minutes. |
For deeper diagnostics, tail the server log in real time:

NetScout Cloud is the hosted version of NetScout. The web dashboard is served from a cloud gateway and all scan data is stored in Supabase — a fully-managed PostgreSQL database with row-level security per tenant. A lightweight local agent runs on any machine on your network, performs the actual scanning and monitoring, and pushes results to the cloud every 30 seconds.
From your perspective the experience is identical to running NetScout locally: the same pages, the same features, the same real-time data. The key difference is that you can access your dashboard from anywhere without being on the same network as the scanning server.
Three components work together to deliver the cloud experience:
| Component | Where it runs | What it does |
|---|---|---|
| Cloud Gateway | Render (cloud) | FastAPI app — serves the web UI, handles auth, exposes the read API for your browser, and accepts agent data pushes via /api/v2/* |
| Supabase | Supabase (cloud) | PostgreSQL + auth. Stores all scan data per tenant with row-level security — tenants never see each other's data |
| Local Agent | Your network | Runs main.py on any Mac / Linux / Windows machine, performs all scanning and monitoring, pushes results every 30 s over HTTPS to the cloud gateway |
Data flow
Tenant isolation — each NetScout Cloud account is a separate tenant. Row-level security (RLS) in Supabase ensures every data read is automatically filtered to your tenant only. The account creator is the tenant owner (admin role); additional users you invite get the user role by default.
Agent token — the agent authenticates to the cloud gateway using an opaque agent_token stored in netscout.conf [cloud]. This token maps the agent to your tenant. Treat it like a password — if compromised, regenerate it from the Connect Agent page.
Agent identity — each agent reports a human-readable agent_id (defaults to the machine hostname). If you run multiple agents on different network segments, set a unique agent_id in netscout.conf [cloud] so you can tell them apart in the Admin panel.
The scanner runs a multi-phase discovery pipeline against the target CIDR on the agent machine:
| Phase | Method | What it finds |
|---|---|---|
| Host Discovery | ARP sweep + ICMP ping | All IP addresses with a live host |
| Port Scan | nmap TCP SYN scan (top 1 000 ports) | Open ports, service names |
| Service Detection | nmap version probe (-sV) | Product names, versions, banners |
| OS Fingerprint | nmap OS detection (-O) | Probable OS and version |
| MAC Lookup | OUI database | Manufacturer / vendor name |
| Hostname | Reverse DNS | Friendly device name |
Filters — Use the filter bar to show Active, Passive, or Risky devices. Free-text search matches IP, hostname, vendor, and MAC address.
Pagination — Device cards are shown 9 per page with ‹ / › navigation.
Editing devices — Click a device card to open its detail sheet. You can override the auto-detected hostname, vendor, and device type. Edits persist across scans.
Tap Assess on any device to launch a deep scan. The engine probes all ports, detects software versions, and cross-references them against a local CVE database.
Each finding includes a title & affected service, CVSS score (0.0–10.0, colour-coded Critical / High / Medium / Low), description, CVE IDs, and a concrete remediation step.
Assessments persist in Supabase and survive agent restarts. Risk levels are reflected immediately on device cards without re-scanning.
The NIDS passively sniffs all IP traffic on the agent's network interface using Scapy. Detection rules operate on a 60-second sliding window:
| Alert Type | Trigger | Severity |
|---|---|---|
| Port Scan | ≥ 10 distinct destination ports from one source | HIGH |
| SYN Flood | ≥ 100 SYN-only packets from one source | CRITICAL |
| Brute Force | ≥ 5 connections to SSH, RDP, FTP, Telnet, etc. | HIGH |
| ICMP Flood | ≥ 50 ICMP packets from one source | HIGH |
| Suspicious Port | Connection to known C2 / malware ports | MEDIUM |
The NIDS auto-starts when the agent launches. Event history is pushed to Supabase in real time. The Recent Alerts table supports filter controls for IP, Severity, Category, and Time window.
Agent-less — no software is installed on target machines. NetScout connects over SSH (Linux/macOS), WinRM (Windows), or SNMP and runs read-only inspection commands to detect misconfigurations and signs of compromise.
What it checks: SSH configuration · firewall state · kernel & auto-updates · failed login attempts · installed packages · running services
To run a scan — Go to the Devices page, click 🔑 on a host, enter SSH (or WinRM / SNMP) credentials, and click Run Authenticated Scan. Results appear on the HIDS page and are pushed to Supabase immediately.
Persistent event log — every scan's findings are appended (up to 2 000 events). Re-scanning the same host adds new entries rather than overwriting old ones.
Deep per-device inspection without requiring root access or installing agents on target machines. Five complementary scan modes:
| Scan Mode | What it does | Root needed |
|---|---|---|
| Full | Runs all four modes below in sequence. | No |
| Traffic | Local connection table (netstat/ss/lsof) + optional tshark capture + NIDS event correlation. | No |
| Endpoint | TCP-connect port scan, HTTP banner grabs, SSL certificate inspection, SNMP probe. | No |
| IoT / UAC | Compares open ports against expected-port baselines for device type. Flags Telnet, FTP, MQTT, RDP, VNC, SMB, Redis, MongoDB, etc. | No |
| Dead-box SSH | Read-only commands over SSH using saved device credentials. Credentials are in-agent-RAM only. | No |
Scheduled sweep — a full forensic scan of all active devices runs automatically every 3 days at 01:00 local time on the agent machine. Results are pushed to the cloud and persist across agent restarts.
Device Isolation (admin-only) — enable the Enable Isolation toggle in the toolbar. Once enabled, device cards show an Isolate button that cuts the device's network path via ARP-poisoning (Scapy) or a firewall block rule (pfctl / iptables). The command is sent to the agent over the heartbeat channel.
The Events page merges NIDS alerts and HIDS findings into a single chronological log. Seven independent filter controls:
| Filter | Values |
|---|---|
| IP | Free-text match against source IP |
| Search | Free-text match against title, detail, and category |
| Source | All Sources / NIDS / HIDS |
| Category | NIDS categories (Port Scan, SYN Flood, …) and HIDS categories (ssh_config, firewall, kernel, …) |
| Severity | All Severities / Critical / High / Medium / Low |
| Type | All Types / Internal / External (RFC-1918 classification) |
| Time | All Time / Last 1 h / 6 h / 24 h / 7 days |
Events are displayed 16 per page. External IPs are highlighted in amber. Source is badged NIDS (purple) or HIDS (green).
An animated canvas-based network map rendering your LAN as a live hierarchy: Internet (top) → Router/Gateway → six group cards fanning out left and right (Active · Open Ports · No Risk on the right; High Risk · Passive · Critical Risk on the left).
Stat chips — the five chips at the top (Devices, Active, Risky, Passive, Open Ports) are clickable links that navigate directly to the Devices page with the matching filter pre-applied.
Node colours: ● Sky blue Internet · ● Purple Router · ● Red Critical · ● Orange High · ● Yellow Medium · ● Blue No Risk · ● Grey Passive
Hover any node for its IP, hostname, vendor, OS, risk level, and open port count. The canvas re-renders automatically after each scan completes.
A strategic security view mapping every detected event — from NIDS and HIDS — onto two industry frameworks. A range selector (1d / 3d / 7d / 14d / 30d) is synced with all other pages.
⛓ Kill Chain Taxonomy — a stage flow strip (Reconnaissance → Delivery → Exploitation → Installation → C&C → Actions on Objectives) followed by a bar chart showing alert volume per stage. Clicking any stage card navigates to the Events page filtered to that stage's categories.
🛡 MITRE ATT&CK® Framework — a grid of 10 enterprise tactic cells (5 per row). Each cell lists the relevant ATT&CK technique IDs with a count of matching events. Purple = NIDS detection · Green = HIDS detection · Grey = no events. Clickable tactics navigate to the Events page.
Measures the real network path — hop by hop — from the agent machine to internet destinations and external SaaS applications. Uses traceroute-style probing to detect where latency, jitter, or packet loss is introduced, and scores the end-to-end experience 0–100.
Slice controls — Device (path to a LAN device) · Application (path to one of 10 monitored SaaS apps) · User (path to the source IP of a user's last login). Pick a slice, then choose a specific entity from the dropdown.
External SaaS Applications — Microsoft 365, Google Workspace, Salesforce, Slack, Zoom, Dropbox, Adobe Creative Cloud, ServiceNow, Workday, HubSpot. Probed automatically every 30 minutes from the agent. Click ↻ Measure now for an on-demand probe.
Hop telemetry — one row per hop showing IP, latency, jitter, packet loss, and status (Good / Average / Poor / Bottleneck). The hop with the largest latency increase is flagged as the bottleneck.
UEBA learns how each user normally behaves, then flags deviations and scores them by risk. Three-stage model: ① Baseline Creation (from login history), ② Anomaly Detection (off-hours logins, new source IPs, external logins, failed-login bursts), ③ Risk Scoring (0–100 — 0–39 ignored · 40–74 watch · 75–100 flagged).
Both the Live Anomaly Feed and Users Monitored tables support sortable columns, pagination, source filter (Real / Demo), and the global range selector (1d / 3d / 7d / 14d / 30d).
Maps NetScout's monitoring to the control requirements of four frameworks — GDPR, HIPAA, PCI DSS, and ISO 27001 — and produces an audit-ready report.
Framework cards — each shows a live readiness ring (% of controls met) plus met / manual / total counts. Click a card to load its control mapping below. Each row shows the control reference, requirement, mapped NetScout evidence (colour-coded badges), and status (✓ Met / ◕ Partial / ✕ Gap / ⚙ Manual).
⤳ Generate Report — produces a print-ready / PDF report covering all four frameworks with readiness percentages and full control tables.
Three tabs, each with its own KPI strip and a searchable, paginated table. The range selector (1d / 3d / 7d / 14d / 30d) is shared across all tabs.
| Tab | Table |
|---|---|
| Vulnerability Assessments | One row per assessed device — IP, hostname, risk level, vulnerability count, last assessment time. |
| Authenticated Scans | One row per HIDS-scanned host — IP, hostname, finding counts by severity, last scan time. |
| User Activity | Complete login / logout event log — timestamp, user, source IP, event type. Up to 1 000 events retained. |
Classifies every discovered device and visualises the fleet in two dimensions.
By Category — nested donut — inner ring = device category (Phone, Laptop, PC, Tablet, Printer, Camera, IoT Device, Router, Server, Other); outer ring = manufacturer within each category. Clicking any arc navigates to Device Inventory with the matching filter.
Tables (paginated, 10 rows/page) — Devices with Threats (worst-first) and Devices by Manufacturer (by count). Each row links to the matching inventory view.
Time-series charts for six network metrics. Use the range selector to switch between 24 h (hourly) and 7 / 14 / 30 / 90-day (daily) views.
| Metric | Description |
|---|---|
| Active Devices | Devices responding at scan time |
| Passive Devices | Devices seen historically but not responding now |
| Risky Devices | Devices with Critical or High vulnerability rating |
| Open Ports | Total exposed ports across all devices |
| Vulnerability Scans | Cumulative per-device assessments run |
| Auth Scans | Cumulative authenticated (SSH/WinRM) assessments run |
History is stored in Supabase and persists regardless of whether the agent is running. The Kill Chain and MITRE ATT&CK visualisations live on the dedicated Security Posture page.
NetScout Cloud uses Supabase JWT authentication. Passwords are hashed and managed entirely by Supabase — NetScout never stores or sees your password. Sessions are governed by Supabase's JWT expiry policy.
Admins can invite additional users to their tenant from Admin → Users.
| Role | Capabilities |
|---|---|
| admin | Full access: User Management, Connect Agent, OTX key config, Speed Test, UEBA, Compliance, agent restart |
| user | Scans, device inventory, threat intelligence views, reports, events, topology, forensics — no admin controls |
Editing a user — click the pencil icon on any row to change name, role, or resend the invite. An admin cannot demote themselves to user (the tenant owner's role is always admin).
Removing a user — click the trash icon. The user's Supabase account is deactivated; they can no longer log in and all their active sessions are invalidated.
In cloud mode the Admin page shows an Agent Status card instead of the local Server Control card. This card reflects the state of your connected local agent.
| Field | Description |
|---|---|
| Status badge | ● Connected (heartbeat received in last 90 s) · ○ Stale (heartbeat overdue) · ● Disconnected (no heartbeat for > 5 min) |
| Agent ID | The agent_id value from netscout.conf [cloud] (defaults to machine hostname) |
| Agent Uptime | Time since the agent last started, computed from the started_at timestamp in the heartbeat |
| Last seen | UTC timestamp of the most recent heartbeat |
Restart Agent — sends a restart command to the agent. The agent picks it up on the next heartbeat cycle (≤ 30 s), performs a graceful shutdown of NIDS and active scans, then re-launches main.py. The dashboard shows Stale during the brief restart window and returns to Connected automatically once the new process sends its first heartbeat.
+ Add Another Agent — click this button (on the Agent Status card in Admin, or on the Connect Agent page) to expand the setup instructions. You can connect multiple agents to the same tenant — for example, one per network segment. Each agent must have a unique agent_id in its netscout.conf.
Agent token — all agents for the same tenant share the same agent_token. Data pushed by each agent is identified by its agent_id and merged into the same tenant data set. If you need to revoke access for a compromised agent token, contact support to regenerate it.
Agent auto-start — to keep the agent running after a reboot, install it as a system service on the agent machine. The agent's own daemon handles this; run:
OTX (AlienVault Open Threat Exchange) enriches every scan with crowdsourced threat data. Configure the API key once — it is stored in Supabase per tenant and shared across all agents on your account.
Configuring the API key
What OTX adds
| Feature | How it works |
|---|---|
| IP correlation | Every scanned device IP is checked: pulse_count > 0 or reputation < 0 flags the device as a threat |
| Malware samples | Flagged IPs pull /indicators/IPv4/{ip}/malware — sample count and pulse names attached |
| IOC lookup | Ad-hoc lookup for IPv4, IPv6, domain, hostname, URL, MD5/SHA1/SHA256, CVE |
| Threat pulses | Subscribed OTX pulses with tags, TLP, targeted countries, MITRE ATT&CK IDs |
| CVE enrichment | Any CVE found by the vulnerability scanner can be enriched via OTX |
Auto-correlation triggers — correlation runs automatically when: a network scan completes, a NIDS event fires, or an authenticated assessment completes. Results are persisted in Supabase. A 50-run ring buffer retains threat-positive correlation history.
Threat Intelligence tab
The Threat Intelligence page (left nav, shield icon — visible to all authenticated users once OTX is configured) is the primary view. A KPI strip at the top shows live counts from your subscribed OTX pulse corpus:
| KPI | What it measures |
|---|---|
| Subscribed Pulses | Total OTX threat pulses you follow — links to OTX browse page |
| Devices Correlated | Number of scanned devices checked in the last correlation run |
| Recent Pulses | Pulses updated in the last 30 days (active threat feed freshness) |
| Malware Families | Unique malware families tracked across all subscribed pulses |
| MITRE Techniques | Unique MITRE ATT&CK® technique IDs referenced across all subscribed pulses — links to attack.mitre.org |
Automatic correlation — no action needed
When OTX is configured, correlation runs automatically in the background every time one of these events occurs:
| Trigger | When it fires |
|---|---|
| scan_complete | After every network scan (manual or scheduled) |
| nids_event | After each NIDS intrusion alert |
| auth_scan | After an authenticated (HIDS) assessment completes |
Results are persisted to Supabase instantly. Only runs that found at least one threat are saved to the correlation history.
How correlation works
For each scanned device IP the engine queries OTX in two steps:
Each match record includes: IP · hostname · vendor · pulse count · reputation score · country · ASN · malware sample count · pulse names (threat actor context).
IOC Lookup
The IOC Lookup card on the Threat Intelligence page lets you query OTX for any indicator on demand. Supported types:
Each lookup queries six OTX sections simultaneously: general, reputation, geo, malware, url_list, and passive_dns. CVEs found by the Vulnerability Assessment engine can also be enriched individually — click the CVE ID on any assessment result to open the OTX enrichment panel.
Threat Pulses
The Pulses card lists your subscribed OTX threat pulses — the crowdsourced intelligence feeds published by researchers and the security community. Each pulse card shows:
Use the modified since date filter to narrow to recently updated pulses. The full pulse corpus is cached for 5 minutes server-side to avoid rate-limiting during repeated searches.
Network Device Correlation
The Network Correlation card shows the most recent correlation run and lets you trigger a manual correlation at any time with the Correlate Now button. Results show:
The Correlation History card shows the last 50 threat-positive runs (paginated, 5 per page) with timestamp, trigger source, and per-run threat/clean counts.
Integration Validation Report
Auto-Correlation Triggers — fires without user action
Correlation Pipeline — per scanned device IP
| Symptom | Likely cause | Fix |
|---|---|---|
| Agent Status shows Disconnected | Agent not running, or wrong gateway_url / agent_token | Check the agent terminal for errors. Verify netscout.conf [cloud] has enabled = true and the correct gateway_url and agent_token from the Connect Agent page. |
| Agent connects but dashboard shows no devices | No scan has run yet | Click Scan Network on the NetScout page to trigger the first scan. The agent will also auto-scan at the next :00 4-hour boundary. |
| Dashboard data is stale or not updating | Agent push cycle delayed or agent stopped | Check the Agent Status card in Admin — it shows the last heartbeat time. If stale (> 90 s), check the agent terminal. The push cycle is every 30 seconds. |
| Login fails with Invalid login credentials | Wrong email / password, or account not yet activated | Check your email for the invite link and confirm you set a password. Use the Forgot Password flow on the login screen to reset. |
| Logged out unexpectedly | JWT expired or a 401 from the gateway | This is normal when the Supabase JWT TTL elapses. Log in again. If it happens every few minutes, check that your Render instance is not restarting frequently (free Render instances sleep after inactivity). |
| NIDS shows Permission denied | Agent not running as root on the agent machine | Restart the agent with sudo .venv/bin/python main.py (macOS / Linux). On Windows, run PowerShell as Administrator. |
| Scan finds 0 devices | Wrong CIDR auto-detected, VPN active on agent machine, or firewall blocking ARP | Check network adapter on the agent machine. Disable VPN. ARP sweeps only work on the same LAN segment as the agent. |
| Threat Intelligence shows OTX API Key Not Configured | No OTX key saved for this tenant | Go to Admin → Threat Intelligence, paste your key, and click Save. Get a free key at otx.alienvault.com. |
| Topology page blank after login | No scan data yet, or canvas not initialised | Run a manual scan first. Hard-refresh the browser (Cmd+Shift+R / Ctrl+Shift+R) to clear any cached JS. |
| Connect Agent page shows a spinning token loader indefinitely | JWT expired or user is not the tenant owner | Log out and back in. If you are an invited user (not the tenant owner), the Connect Agent page requires admin role — ask the tenant owner. |
| Agent.zip download fails or is empty | Render instance sleeping (free tier) or gateway error | Visit the dashboard URL directly first to wake the Render instance, then retry the download. On free Render plans the instance spins down after 15 minutes of inactivity. |
These flows describe the end-to-end journey for each of the three roles on the platform — from first visit through day-to-day use.
netscout.conf: pastes gateway URL and agent token → starts the agentgit push origin main → Render auto-deploys in ~2 minThree roles exist on the platform. Role is enforced server-side on every API request — the UI hides elements for unauthorised roles but the backend independently rejects unauthorised calls.
| Feature / Action | User | Admin | Portfolio Admin |
|---|---|---|---|
| Dashboard & Monitoring | |||
| View Topology map | ✓ | ✓ | ✓ |
| View Device Inventory | ✓ | ✓ | ✓ |
| View NIDS / HIDS alerts | ✓ | ✓ | ✓ |
| View Network Path & UX | ✓ | ✓ | ✓ |
| View Security Posture (Kill Chain / MITRE) | ✓ | ✓ | ✓ |
| View Compliance & Reports | ✓ | ✓ | ✓ |
| View Threat Intelligence (OTX) | ✓ | ✓ | ✓ |
| View Activity Dashboard & History | ✓ | ✓ | ✓ |
| View UEBA (User & Entity Behaviour) | ✓ | ✓ | ✓ |
| View Forensics results | ✓ | ✓ | ✓ |
| View Speed Test history | ✓ | ✓ | ✓ |
| Scan & Assessment Actions | |||
| Trigger manual network scan | ✗ | ✓ | ✓ |
| Trigger vulnerability assessment | ✗ | ✓ | ✓ |
| Trigger forensic scan on a device | ✗ | ✓ | ✓ |
| Arm / disarm Shadow IT monitoring | ✗ | ✓ | ✓ |
| Start / stop NIDS | ✗ | ✓ | ✓ |
| Run authenticated vulnerability assessment | ✗ | ✓ | ✓ |
| Trigger path probe on demand | ✗ | ✓ | ✓ |
| Trigger OTX threat correlation | ✗ | ✓ | ✓ |
| Settings & Configuration | |||
| Edit scan / assessment schedules | ✗ | ✓ | ✓ |
| Configure webhook alerts | ✗ | ✓ | ✓ |
| Set / update OTX API key | ✗ | ✓ | ✓ |
| Edit device labels / overrides | ✗ | ✓ | ✓ |
| Manage Shadow IT whitelist | ✗ | ✓ | ✓ |
| View Admin Guide | ✗ | ✓ | ✓ |
| User & Agent Management | |||
| View user list & roles | ✗ | ✓ | ✓ |
| Invite / remove users | ✗ | ✓ | ✓ |
| Promote user to admin | ✗ | ✓ | ✓ |
| View & revoke user sessions | ✗ | ✓ | ✓ |
| View Agent status & heartbeat | ✗ | ✓ | ✓ |
| Restart agent remotely | ✗ | ✓ | ✓ |
| Trigger remote scan from cloud | ✗ | ✓ | ✓ |
| Portfolio Admin Only | |||
| Switch between tenants | ✗ | ✗ | ✓ |
| View all tenants (tid, type, expiry) | ✗ | ✗ | ✓ |
| Extend tenant trial (+7 days) | ✗ | ✗ | ✓ |
| Promote tenant Trial → Customer | ✗ | ✗ | ✓ |
| Deploy gateway code changes | ✗ | ✗ | ✓ |
| Access Supabase directly | ✗ | ✗ | ✓ |
| Access Render / Logfire dashboards | ✗ | ✗ | ✓ |
| View Platform Architecture Guide | ✗ | ✗ | ✓ |
NetScout is a commercial multi-tenant SaaS network intelligence and security monitoring platform. It consists of a lightweight local agent that customers install on any machine on their network, and a cloud gateway that aggregates agent data into a per-tenant Supabase database accessible from any browser.
The platform is designed for SMB and enterprise network owners who need real-time visibility into devices, threats, and network health without a complex on-premises installation. The agent does all the heavy lifting (nmap scans, packet capture, vulnerability assessment) while the cloud provides the always-on dashboard.
| Dimension | Detail |
|---|---|
| Current version | v1.9 + (see git log — no single version string; releases are tagged in commit messages) |
| Total git commits | 256 (as of June 2026) |
| Repository | github.com/rsri22/netscout (private) |
| Cloud host | Render — netscout-1j55.onrender.com |
| Database | Supabase (PostgreSQL + Auth) |
| Platform admin email | [email protected] (SA_EMAIL env var on Render) |
| Primary local dev path | /Users/spongebob/Downloads/prg/netscout/ |
Three tiers work together:
| Tier | Component | Host | Role |
|---|---|---|---|
| Agent | main.py + modules | Customer machine | Scans the local network; runs nmap, captures packets, assesses vulns, pushes results to cloud every 30 s |
| Gateway | railway_app.py | Render | Receives agent pushes; serves the web UI; handles auth; reads/writes Supabase |
| Database | Supabase | Supabase cloud | PostgreSQL store with per-tenant RLS; Supabase Auth handles JWT issuance and user management |
Request flow (browser):
Agent push flow:
Deployment pipeline:
Private repository. Main branch = production. Every push to main triggers an automatic Render deploy. There is no staging branch — test locally before pushing. Render has a CI guard (tenant isolation test via ci: auto-revert on tenant isolation failure commit) that auto-reverts on failure.
| Item | Detail |
|---|---|
| Repo | github.com/rsri22/netscout (private) |
| Deploy trigger | Push to main branch |
| Commit style | Conventional commits: feat/fix/ci + version tag in message |
| Total commits | 256 as of June 2026 |
Render hosts the FastAPI gateway (railway_app.py). The service is named netscout-1j55 and is deployed from the GitHub repo automatically.
| Item | Detail |
|---|---|
| Service URL | https://netscout-1j55.onrender.com |
| Current plan | Free (spins down after 15 min inactivity) |
| Keepalive | JS ping in web UI every 10 min while user logged in; local cron job every 14 min while Claude Code is open |
| Upgrade trigger | First paying customer → Starter plan ($7/mo, no spin-down) |
| Runtime | Python 3.11.9 (runtime.txt) |
| Build | nixpacks; pip install -r requirements-gateway.txt |
| Start command | uvicorn railway_app:app --host 0.0.0.0 --port $PORT |
| Health check | GET / → 200 (healthcheckTimeout = 30 s) |
| Restart policy | on_failure (railway.toml) |
| Logs | Render dashboard → Logs tab; errors also sent to Logfire |
railway.toml, Procfile) but is deployed on Render, not Railway. The railway.toml build/deploy config is compatible with Render's nixpacks builder and is intentionally kept for portability.
Supabase provides PostgreSQL storage with Row-Level Security per tenant, and a managed Auth service (JWT issuance, email confirmation, password reset).
| Item | Detail |
|---|---|
| Current plan | Free tier (500 MB DB, 50k MAU auth) |
| Auth model | Supabase Auth (email+password); JWTs verified server-side via /auth/v1/user |
| Key tables | tenants, devices, scan_history, assessment_history, nids_events, hids_events, shadow_it_events, auth_scan_history, correlation_history, path_history, activity_log, agent_history |
| Tenant isolation | All tables have tenant_id column; RLS policies filter reads; gateway always injects tenant_id on writes (service role key) |
| Connection | Service role key used server-side only (never sent to agents or browser) |
| Anon key | Used for auth API calls (safe to use server-side) |
| Password reset | Delegated to Supabase email flow (/auth/v1/recover) |
| Email confirm | Configured in Supabase project settings; Supabase sends confirmation emails |
| Connection timeout | 30 s (increased from default — commit dd6aa80) |
Key Supabase tables:
| Table | Key columns | Notes |
|---|---|---|
| tenants | id, owner_id, name, tid, ttype, agent_token, trial_expires_at, agent_utc_offset_hours | One row per customer. tid = human ID (M001/T7xxx/C11xxx) |
| devices | tenant_id, ip, mac, hostname, vendor, os, ports, last_seen | Upserted on every agent sync; keyed (tenant_id, ip) |
| scan_history | tenant_id, scan_time, device_count, new_devices | Appended on each network scan |
| assessment_history | tenant_id, scan_time, ip, findings, severity | Ordered by scan_time DESC (not id — see decisions) |
| nids_events | tenant_id, time, category, src_ip, dst_ip, severity, detail | Immediate push on alert; also in nids_events.json locally |
| hids_events | tenant_id, time, type, detail | Host-level anomalies (process, file, login changes) |
| activity_log | tenant_id, time, user, ip, event, location | Login events; used by UEBA page |
| agent_history | tenant_id, time, event, detail | Lifecycle events (start/stop/restart/crash); pruned after 30 days |
| path_history | tenant_id, time, target, hops, latency_ms | Network path probes; cached in-process with short TTL |
| correlation_history | tenant_id, scan_time, matched_iocs, pulse_id | OTX threat correlation results |
Logfire (by Pydantic) is wired into the FastAPI gateway for error monitoring. Only ERROR and CRITICAL log events are forwarded to keep usage within the free tier.
| Item | Detail |
|---|---|
| Integration | logfire.configure(send_to_logfire="if-token-present"); logfire.instrument_fastapi(app) |
| Activation | Set LOGFIRE_TOKEN env var on Render; silently no-ops if absent |
| Added in | v1.9 (commit a68c931) |
| Cost | Free tier |
| Dashboard | logfire.pydantic.dev — log in with the project credentials |
Open Threat Exchange (OTX) provides real-time threat intelligence pulses. The agent correlates discovered device IPs and domains against OTX indicators of compromise (IOCs).
| Item | Detail |
|---|---|
| API key storage | Stored in Supabase per-tenant (not in netscout.conf); also overridable via OTX_API_KEY env var on Render |
| Correlation trigger | After every scan, assessment, NIDS event, and on-demand |
| Admin endpoint | POST /api/admin/otx-key — save key; POST /api/admin/otx-key/test — verify key |
Speed tests run on the agent machine using speedtest-cli with threads=8 as primary. A fallback uses Ookla raw-socket downloads if speedtest-cli fails. Cloudflare was tested and rejected (returns HTTP 429 for >5 MB downloads).
nmap is the core scanning engine on the agent. Used for host discovery (ARP + ICMP), service version detection (-sV), OS fingerprinting (-O), and vulnerability scripts (--script vuln). Must be installed on the agent machine; agent will fail to scan without it.
The NIDS module (nids.py) uses scapy for raw packet sniffing. Requires root/sudo on the agent machine. On Windows, Npcap must be installed in WinPcap-compatible mode.
The entire platform was built using Claude Code (claude-sonnet-4-6) as the primary development assistant. All 256 commits were co-authored with Claude Code. The local cron job that keeps Render alive is also managed through Claude Code's scheduled tasks system.
The gateway runs on Render and is the only component that talks to Supabase with the service role key. Agents and browsers never receive Supabase credentials.
| File | Role |
|---|---|
| railway_app.py | FastAPI app entry point. Mounts cloud_gateway and cloud_read_gateway routers. Serves /ui (web UI), /tos, /privacy, /agent.zip, /health. Runs startup seeding (_seed_on_startup) on every deploy to backfill missing tenant tids. Contains _CLOUD_TS_PATCH (JS injected into web UI) and _CLOUD_README_HTML (cloud admin guide). Build: nixpacks; Start: uvicorn. |
| cloud_gateway.py | Push endpoints: /api/v2/*. Agents POST scan data here. Every request validated against x-agent-token header → resolves to tenant_id. Handles: device upsert, scan history, assessments, NIDS/HIDS events, shadow IT, forensics, path probes, heartbeats, agent lifecycle events, speed test results, correlation results. Maintains in-memory stores: _pending_auth_creds (5-min TTL), _auth_assess_results, _agent_start_times, _agent_lifecycle_events (200 events/tenant cap). |
| cloud_read_gateway.py | Read + auth endpoints: /api/*. All 60+ read endpoints. JWT verification via _user_ctx dependency. Super admin backdoor (SA_EMAIL env var). Tenant management endpoints (promote, activate, list). All data reads filtered by tenant_id. Includes rate limiting (slowapi), in-process path cache (short TTL), trial enforcement (_check_trial_active). |
| agent_config.py | Single source of truth for all config. Reads [cloud] section from netscout.conf on agent machines. On gateway, reads Supabase credentials from env vars. Shared by cloud_gateway.py and cloud_push.py. |
| requirements-gateway.txt | Gateway-only dependencies: fastapi, uvicorn, pydantic, httpx, supabase, slowapi, logfire[fastapi]. Separate from requirements.txt (agent deps include nmap, scapy, etc.). |
| Route group | File | Auth required |
|---|---|---|
| GET /health, GET / | railway_app.py | None (public) |
| GET /ui, /tos, /privacy | railway_app.py | None (static pages) |
| GET /agent.zip | railway_app.py | None (public download) |
| POST /api/v2/* (push) | cloud_gateway.py | x-agent-token header |
| POST /api/auth/login, /register, /forgot-password | cloud_read_gateway.py | None |
| GET /api/auth/me | cloud_read_gateway.py | Supabase JWT |
| GET /api/devices, /api/history, /api/assess, etc. | cloud_read_gateway.py | Supabase JWT + trial check |
| GET /api/admin/* (speedtest, otx-key, users, sessions) | cloud_read_gateway.py | JWT + role=admin |
| GET /api/admin/tenants, PATCH /api/admin/tenant/* | cloud_read_gateway.py | JWT + SA_EMAIL match |
The web UI (backend/web/index.html) is a local-server UI that is adapted for cloud at serve time in serve_ui(). Two HTML/JS blocks are injected before </body>:
<div> swapped into #view-readme on DOMContentLoaded.The agent runs on the customer's machine. All scan operations happen locally; results are pushed to the cloud gateway. The agent is distributed via /agent.zip (built dynamically from the gateway, excluding cloud-only files and sensitive JSON data).
| File | Role |
|---|---|
| main.py | FastAPI local server (port 8765). Serves the local web UI. Handles WebSocket connections. Orchestrates all feature modules. On startup: registers all cloud push callbacks. Exposes /api/* endpoints for the local UI. ~5,300 lines. |
| cloud_push.py | Dual-write sync layer. Polling loop (every 30 s, configurable) reads all local JSON files and pushes only changed data since last cycle. Immediate push for NIDS alerts, shadow IT events, and scan progress. All failures are caught and logged — never propagate to local server. ~925 lines. |
| scanner.py | nmap host discovery (ARP + ICMP ping sweeps) and port scanning. Resolves hostnames, identifies vendors from MAC OUI table (mac_lookup.py). Auto-scans every 4 hours. |
| vuln_assess.py | Deep port scan (TCP/UDP), service version detection (-sV), CVE lookup against local knowledge base. Classifies findings as Critical/High/Medium/Low. Daily auto-assessment at 10:00. |
| nids.py | Network Intrusion Detection System. Uses scapy for raw packet capture. Fires alert events to cloud immediately (not waiting for 30 s poll). Timestamps always in local time (intentional — see decisions). |
| forensics.py | Deep forensic analysis per device: full port scan, OS fingerprint, service banner grab, connection state. Supports isolation mode (firewall rule injection). |
| path_probe.py | Network path probing (traceroute-style) to internet targets (1.1.1.1, etc.) every 10 min and SaaS apps every 30 min. Results pushed to Supabase path_history. |
| auth_assess.py | Authenticated vulnerability assessment — tries supplied credentials against SSH/RDP/HTTP to test access controls. Results relayed via in-memory cache (never written to Supabase). |
| netscout-daemon.py | Process watchdog. Monitors main.py and restarts it on crash. Installed as a launchctl service (com.netscout.server) on macOS. |
| netscout.conf | Agent configuration: server host/port, cloud gateway URL, agent token, push interval, sudo password (chmod 600 — never logged). Template shipped in agent.zip with placeholder values. |
| Type | ID Series | Trigger | Constraints |
|---|---|---|---|
| Master | M001 (singleton) | Registration with @incytes.net email | One only. Platform owner. |
| Trial | T7000, T7001, … | All other new registrations | 7-day trial; all reads blocked after expiry (403 trial_expired). Extension via PATCH /api/admin/tenant/activate (+7 days). Super admin only. |
| Customer | C11001, C11002, … | Promoted from Trial via PATCH /api/admin/tenant/promote | No expiry. Future: Stripe subscription_status check. |
Each tenant in Supabase has an agent_token (random 32-byte URL-safe string generated at registration). The agent includes this token in every push request via the x-agent-token header. The gateway resolves it to a tenant_id and injects that into all written rows — agents never know their own tenant UUID.
All Supabase tables have a tenant_id column. Row-Level Security policies ensure that reads via the anon/user key are filtered to the authenticated tenant. The gateway uses the service role key (bypasses RLS) and manually injects tenant_id on every write and .eq("tenant_id", ctx.tenant_id) on every read — belt-and-suspenders isolation.
One tenant can run multiple agents on different networks. Each agent has a unique agent_id (defaults to machine hostname; overridable in netscout.conf). All agents share the same agent_token and push to the same tenant. The dashboard shows which agent last pushed data via the Agent Management section.
| Flow | Detail |
|---|---|
| Login | POST /api/auth/login → Supabase sign_in_with_password → returns Supabase JWT stored in localStorage as netscout_token |
| Token verification | _user_ctx() FastAPI dependency: calls GET /auth/v1/user with Bearer token → decodes user_id and email → resolves tenant_id via _user_to_tenant() (lru_cache) |
| Roles | "admin" = tenant owner or invited user with role:admin in user_metadata. "user" = standard member. Role checked per-endpoint. |
| Super admin | Email matches SA_EMAIL env var → bypasses normal tenant lookup → can switch to any tenant via X-Tenant-ID header. _ensure_super_admin() seeds this user into every new tenant on registration. |
| Registration | POST /api/auth/register → Supabase signup → waits up to 5 s for trigger to create tenants row → falls back to direct insert → assigns tid/ttype via _assign_tid() → seeds super admin via _ensure_super_admin() |
| Password reset | POST /api/auth/forgot-password → Supabase /auth/v1/recover → Supabase sends reset email with magic link |
| Team members | Invited users get tenant_id in user_metadata. Owner lookup checks tenants.owner_id; member lookup checks user_metadata.tenant_id. |
| Step | What happens | Cadence |
|---|---|---|
| 1. Local scan | scanner.py runs nmap; results written to devices.json, history.json | Every 4 hours + on-demand |
| 2. Push loop | cloud_push.py polling loop reads changed JSON files; POSTs to /api/v2/* on Render | Every 30 s |
| 3. Immediate push | NIDS alerts, shadow IT events, scan progress POSTed directly by event handlers | Instant (sub-second) |
| 4. Gateway write | cloud_gateway.py validates agent token, injects tenant_id, upserts rows in Supabase | On receipt |
| 5. Browser read | Dashboard JS fetches /api/* with JWT; cloud_read_gateway.py reads Supabase filtered by tenant_id | On page load + polling |
| 6. Heartbeat | Agent sends heartbeat every ~30 s with uptime, agent_id, start_time; shown in Agent Management panel | Every 30 s |
sorted(..., key=lambda r: r.get("time",""), reverse=True)) — do not rely on .order("time", desc=True) on TEXT columns (unreliable in PostgREST).ORDER BY scan_time DESC with a date cutoff — never ORDER BY id DESC (IDs assigned in send-order by _sync_list_prepend, so oldest scans get highest IDs)._sync_list_prepend (not _sync_list) for JSON files that use insert(0,...) (assessment_history, auth_scan_history, correlation_history).All of these must be set in the Render dashboard under Environment for the netscout-1j55 service. Never commit these to git.
| Variable | Required | Description |
|---|---|---|
SUPABASE_URL | Yes | Supabase project URL (https://xxx.supabase.co) |
SUPABASE_SERVICE_KEY | Yes | Supabase service role key — server-side only, full DB access bypassing RLS |
SUPABASE_ANON_KEY | Yes | Supabase anon/public key — used for auth API calls |
SA_EMAIL | Yes | Platform super admin email ([email protected]). Never expose in source. |
SA_PASS | Yes | Platform super admin password. Never expose in source. |
ALLOWED_ORIGINS | Yes | Comma-separated CORS origins (e.g. https://netscout.incytes.net,https://netscout-1j55.onrender.com) |
OTX_API_KEY | No | AlienVault OTX API key (overrides per-tenant key in Supabase for all tenants) |
LOGFIRE_TOKEN | No | Logfire project token — error monitoring. Silently disabled if absent. |
PORT | Auto | Set automatically by Render. Passed to uvicorn. |
Agent-side config (netscout.conf [cloud] section):
| Key | Value |
|---|---|
| enabled | true |
| gateway_url | https://netscout-1j55.onrender.com (or custom domain once set up) |
| agent_token | Token from tenants.agent_token in Supabase (unique per tenant) |
| push_interval_seconds | 30 (default) |
backendpip install -r requirements-gateway.txtuvicorn railway_app:app --host 0.0.0.0 --port $PORT/Agents download their own code from /agent.zip. To update a customer agent: push changes to main (Render auto-deploys), then on the customer machine:
netscout.conf (it ships as a template with placeholder values). Customer agent tokens and passwords are preserved.
All of these operations are available from the Tenant KPI card in the dashboard header (visible only when logged in as the platform super admin).
| Operation | How | API |
|---|---|---|
| View all tenants | Click "Switch Tenant" button in the Tenant KPI card → dropdown lists all tenants with tid, ttype, expiry | GET /api/admin/tenants |
| Switch to a tenant | Click any tenant in the switcher dropdown → dashboard reloads in context of that tenant | X-Tenant-ID header injected into subsequent requests |
| Extend trial (+7 days) | Click "Activate (+7d)" button (visible on expired Trial tenants) | PATCH /api/admin/tenant/activate |
| Promote to Customer | Click "Promote to Customer" button (visible on Trial tenants) | PATCH /api/admin/tenant/promote → assigns next C##### tid |
| Manage users | Admin → Settings → Users tab (visible to any admin within a tenant) | GET/POST/PATCH/DELETE /api/admin/users |
| View sessions | Admin → Settings → Sessions tab | GET /api/admin/sessions |
| Direct Supabase | Log in to supabase.com → project → Table Editor for any manual data operations | N/A |
_seed_on_startup() runs automatically. It iterates all tenants, calls _ensure_super_admin() on each (adds super admin to any new tenant), and backfills missing tid/ttype. Safe to run repeatedly.
| Layer | Protection |
|---|---|
| Supabase service key | Server-side only (Render env var). Never sent to agents or browsers. All agent pushes use only the agent_token. |
| Agent tokens | 32-byte URL-safe random strings. Stored in Supabase tenants table. Sent only in x-agent-token header over HTTPS. |
| JWT verification | Every /api/* request (except auth endpoints) passes through _user_ctx() which calls Supabase /auth/v1/user — no local token parsing. |
| Tenant isolation | Belt-and-suspenders: Supabase RLS + explicit .eq("tenant_id") on every gateway read. CI tenant isolation guard (static test in git) auto-reverts any deploy that breaks it. |
| Rate limiting | slowapi on all auth endpoints (5/min for login, register, forgot-password). Real IP from X-Forwarded-For header (Render proxy). |
| CORS | Strict allowlist via ALLOWED_ORIGINS env var. Added in v1.6 (commit 60be403). |
| sudo password | Stored in netscout.conf [privileges] on agent machine. chmod 600. Never logged, never sent over network. Passed only via encrypted stdin to sudo. |
| SSH/auth credentials | Relayed in-memory only (_pending_auth_creds dict, 5-min TTL). Never written to Supabase or disk. |
| Super admin | Email-matched in SA_EMAIL env var. Credentials stored only in Supabase Auth + Render env vars. TODO: move SA_PASS from source to env var (pending task). |
| Legal pages | Terms of Service (/tos) and Privacy Policy (/privacy) live on the gateway. Added v1.7. |
| Decision | Rule | Reason |
|---|---|---|
| Timestamps — NIDS/HIDS | Always use datetime.now() (local time). Never UTC. Frontend displays as-is. | Converting to UTC and back caused a double-offset bug — events appeared at wrong time by the full UTC offset amount. |
| assessment_history sort | ORDER BY scan_time DESC, never ORDER BY id DESC | _sync_list_prepend sends newest first; Supabase assigns IDs in send-order, so oldest scans end up with highest IDs. |
| _sync_list_prepend vs _sync_list | Use _sync_list_prepend for files using insert(0,...) at head; _sync_list for append-at-tail files. | _sync_list reads data[last:] (tail) — misses new entries prepended at head. Caused assess-all results to never reach Supabase. |
| Speed test fallback | speedtest-cli (threads=8) → Ookla raw socket. Never Cloudflare. | Cloudflare returns HTTP 429 for downloads >5 MB. |
| Railway vs Render naming | Deployed on Render; railway.toml and Procfile kept for portability. | railway.toml build/start config is compatible with Render nixpacks builder. No functional difference. |
| netscout.conf never in agent.zip | agent.zip always ships a clean template with placeholder values. | Prevents leaking the platform admin's own agent_token and sudo_password to customers. |
| Cloud-only files excluded from agent.zip | cloud_gateway.py, cloud_read_gateway.py, railway_app.py, railway.toml, Procfile, nginx.conf, netscout.conf excluded. | These contain server-side logic and env-var references that are meaningless and potentially confusing on an agent machine. |
| # | Item | Phase | Blocker for |
|---|---|---|---|
| 1 | Cloudflare + custom domain (app.netscout.incytes.net) | 1 | Professional appearance before sharing URL publicly |
| 2 | Move SA_EMAIL/SA_PASS from source to Render env vars | 1 | Security — already flagged as background task |
| 3 | Deploy netscout-dashboard (Next.js) to Vercel | 1 | Marketing landing page |
| 4 | Upgrade Render to Starter ($7/mo) | 1 | First paying customer |
| 5 | Stripe integration — checkout, webhook, subscription status | 2 | #1 commercial blocker — no payment path exists today |
| 6 | Pricing page on landing site | 2 | Before sharing URL publicly |
| 7 | Trial expiry → upgrade CTA → Stripe checkout | 2 | Tied to Stripe |
| 8 | Welcome email with agent token on signup (Resend.com) | 3 | Before first external user |
| 9 | Post-signup setup wizard in dashboard | 3 | Onboarding friction |
| 10 | Team invite UI | 3 | When customers ask |
| 11 | One-liner agent installer script | 4 | Before public launch |
| 12 | Flutter app — App Store / Play Store | 4 | Optional; web UI covers this for now |