Architecture
System Components
Horizon is composed of several interconnected components that work together to provide the complete access control and monitoring experience. The Horizon Settings App is a Vite-based frontend application built with vanilla JavaScript that provides the management interface for creating circuits, configuring access policies, managing security rules, and administering user allowlists. The Horizon Logs App is a separate Vite-based frontend application, also built with vanilla JavaScript, that provides the monitoring dashboard with request logs, access logs, 24-hour statistics, and the interactive geographic world map. The Horizon Proxy is the cloud-hosted reverse proxy infrastructure that receives all incoming traffic to *.horizon.mutexercloud.com domains, performs TLS termination, enforces access policies, evaluates IP and country rules, checks for bot signatures, and forwards allowed traffic to the appropriate backend service through the agent. The Core API is the backend API service that handles all CRUD operations for circuits, IP rules, country blocks, user allowlists, and log retrieval, and manages the communication between the proxy layer and the device agents. The Agents are the on-device software components (documented in the Agents section) that receive proxied traffic from the Horizon proxy via the Core API and forward it to the local services at the configured IP address and port.
Traffic Flow
The complete traffic flow for a request passing through Horizon is as follows. A client browser initiates an HTTPS connection to {prefix}.horizon.mutexercloud.com. The DNS for this domain resolves to the Horizon proxy infrastructure in the Mutexer cloud. The proxy performs TLS termination, decrypting the incoming request. The decrypted request then passes through a series of security checks, each of which can independently block the request. The access policy check verifies the user's identity and authorization (for non-public circuits). The IP rule evaluation checks the source IP against any configured whitelist or blacklist CIDR rules. The country block check geolocates the source IP and verifies it does not match a blocked country. The bot and scanner detection layer checks the User-Agent header against known scanner signatures. If the request passes all of these checks, it is forwarded through the Core API to the appropriate Agent, which delivers it to the backend service at the configured internal IP address and port using the configured protocol. The backend service processes the request and returns a response, which travels the reverse path back through the Agent, the Core API, and the proxy, where it is re-encrypted with TLS and delivered to the client browser. The entire request - including its metadata, outcome, and timing - is logged for the monitoring dashboard.
User Browser
|
v
{prefix}.horizon.mutexercloud.com (HTTPS/TLS 1.3 termination)
|
v
Horizon Proxy
+-- Access Policy Check (public / project / user allowlist)
+-- IP Rule Evaluation (whitelist -> blacklist -> allow)
+-- Country Block Check
+-- Bot/Scanner Detection
|
v (if allowed)
Core API -> Agent -> Device Service (HTTP or HTTPS)
|
v
Response back through same path
|
v
Request logged (source IP, country, status, action, user, sizes)Infrastructure
Both frontend applications (Settings and Logs) are containerized using Docker, built on Ubuntu with Apache2 as the web server. Log shipping from the containers is handled by Promtail v2.4.1, which forwards application and access logs to Grafana Loki for centralized, long-term log aggregation and analysis beyond what is visible in the Horizon monitoring dashboard. Apache2 is configured with a comprehensive set of modules including proxy, SSL, rewrite, headers, deflate, and WebSocket support, enabling efficient, secure communication between the frontend applications and the Core API backend.
Authentication Flow
The Horizon Settings and Logs applications are embedded as iframes within the Mutexer platform's main web application. Authentication and context are provided by the parent window through a TransitClient communication channel. When the iframe loads, it requests three pieces of information from the parent window: the projectId (identifying which project's Horizon data to display), the coreApiUrl (the base URL for the Core API), and the token (a JWT authentication token for the currently logged-in user). These values are stored in the browser's localStorage and used by the Axios HTTP client to authenticate all subsequent API requests. Every API call includes the JWT token in an Authorization: Bearer header, and the Core API validates this token to ensure the user is authorized to access the requested project's data. API requests have a 60-second timeout, and error responses (400, 401, 403) are handled gracefully with user-facing error messages.
API Surface
All Horizon API endpoints are scoped to a specific project, following the URL pattern /projects/{projectId}/facets/horizon-project-settings/.... The API surface covers the full lifecycle of circuits and their associated configuration: creating, reading, updating, and deleting circuits; adding and removing IP blacklist and whitelist rules; adding and removing country blocks; updating access policies; managing the user allowlist for Specific Users circuits; toggling circuit enabled status; updating the block scanners setting; setting and clearing expiration dates; and retrieving request logs, access logs, and 24-hour statistics (all returned in a single API call for efficiency). This project-scoped design ensures that each project's Horizon data is fully isolated and that a user can only access circuits and logs for projects they are authorized to view.
