Topology & Architecture
/topology (legacy read-only) and /network-map (interactive editor,
mig 105) both visualise the same graph of nodes and edges.
Three sources populate the graph:
- Auto-detected — Monsys-agents report their own IPs and listening ports; the hub deduces potential connections between agents in the same subnet
- Manual — external services that do not run an agent (SaaS, ISP-uplink, CDN, switches, firewalls, load balancers, NAS/SAN, etc.) are added via the dashboard’s + Device button or
POST /api/v1/topology/nodes - Drawn edges — drag from one node’s handle to another in
/network-mapto create a topology edge with one click (defaults: bidirectional, encrypted=true). Click the edge to edit label/protocol/port/critical/notes.
Multi-map (mig 105)
Each tenant has one or more topology maps — separate canvases for
different datacenters, customers, environments or offices. Switch
between them with the tab strip at the top of /network-map; create
new ones via ”+ nieuwe kaart” with kind = datacenter/customer/
environment/office/other. One map is always marked as the tenant’s
default; calls without ?map_id= resolve to it for backwards-compat.
Pre-mig-105 deployments: a “Default” map is auto-seeded per tenant and all existing nodes/edges/groups are migrated to it on schema upgrade. No operator action required.
Add device (any of 40+ node types)
Click + Device in the toolbar. Type picker is grouped:
- compute — server, vm, container_host, container, serverless
- network — router, switch (managed/unmanaged), firewall, load_balancer, WAF, VPN concentrator, wireless AP, SD-WAN, IDS/IPS, ISP uplink, leased line, VPN tunnel, MPLS circuit
- storage — NAS, SAN, object_storage, backup_appliance
- security — SIEM, PAM, certificate_authority, HSM
- external — SaaS, CDN, DNS provider, email provider, payment gateway, identity provider, cloud provider, monitoring service, ticketing service
- site / org — datacenter, office_location, cloud_region, user_group, customer_network, other
Per-device fields: label, FQDN, IP addresses, MAC addresses, role, environment, criticality, description, vendor, model, management IP/port, owner email, business owner, runbook URL, documentation URL, tags. All editable later by clicking the node.
Contextual PROBLEMS panel
The right-hand alerts panel on /network-map is filtered to the
active map — only open alerts whose agent_id is represented as a
node on the current canvas. “+N other” toggles to show tenant-wide
alerts; the ◧/◨ button collapses the panel for a full-width map.
Data Model
| Table | What it stores |
|---|---|
topology_nodes | servers, VMs, switches, external SaaS — 30+ node types |
topology_edges | connections with protocol, port, encryption, criticality |
topology_zones | network zones / VLANs / subnets / cloud-VPCs |
topology_certificates | TLS certs associated with edges (CN, SAN, expiry) |
topology_node_configs | device-specific configs (markdown), version history |
topology_snapshots | point-in-time JSONB dumps for change tracking |
topology_changes | append-only audit log of who changed what when |
topology_detected_connections | intermediate table: auto-detected but not yet documented |
Tenant isolation via Postgres RLS — each row has a tenant_id and the policy matched that against current_setting('app.current_tenant') on each query.
Auto-Bootstrap
TopologyMatcherWorker runs every 10 minutes and:
- Creates a
topology_nodefor eachis_active=trueagent that doesn’t have one (label = name, type = server, managed_by_monsys = true) - Expands
agent_connections×inventory_ports(only non-loopback) to per-port detection rows intopology_detected_connections
A new Monsys-agent thus appears automatically in the diagram as soon as it pushes inventory (~5 minutes after install).
Detected vs. Documented
Auto-detected connections have is_documented = false. In the Detected tab of the UI (or GET /api/v1/topology/detected?unmatched=1) you see per connection:
- src agent + dest IP + port + protocol
- First/last time seen
- Button Promote → to choose a target_node. That creates an actual
topology_edgewithis_documented = true.
This way the diagram grows organically: each new connection gets a “approve this”-moment for the operator.
API
| Method | Path |
|---|---|
GET /api/v1/topology/nodes | list nodes with agent_status + last_seen |
POST /api/v1/topology/nodes | new node (manual — SaaS, switch, …) |
PATCH /api/v1/topology/nodes/:id | update (whitelist on editable fields) |
DELETE /api/v1/topology/nodes/:id | delete |
GET /api/v1/topology/edges · POST · DELETE /:id | edges CRUD |
GET /api/v1/topology/zones · POST | zones CRUD |
GET /api/v1/topology/detected[?unmatched=1] | auto-detected list |
POST /api/v1/topology/detected/:id/promote | promote → edge |
GET /api/v1/topology/snapshots · POST | snapshots |
GET /api/v1/topology/export/mermaid | Mermaid graph download |
UI
Dashboard has 4 tabs:
- Diagram — React Flow canvas with drag-to-position (position is saved via
PATCH /nodes/:idon each drag-end), drag-to-connect between nodes (creates new edge), keyboardDeleteto delete edges - Detected — promote-flow (see above)
- Snapshots — point-in-time snapshots with node/edge counts
- Nodes & edges — read+delete table-view
Edge styling:
- green solid = encrypted and documented
- red solid + animated = critical
- amber dashed = auto-detected but not documented
Related
- Diagrams — uses this topology as input for PNG/SVG/PDF export with layout algorithms
- Blast radius — uses the same edges for 3-hop reachability per host