Skip to content

Architecture

Ghost is a desktop application made up of multiple processes (separate programs running at the same time on your computer) that work together. This page explains how all the pieces fit together, how data flows through the system, and why the architecture is designed this way.

If you’re a QA engineer who just wants to use Ghost, you don’t need to memorize this — but understanding the big picture helps when troubleshooting or when something isn’t behaving as expected.

Ghost has four main components that communicate over your computer’s local network (nothing goes to the internet — all communication stays on your machine):

What this diagram shows: The entire Ghost system is organized into four layers, each in its own box:

  • Tauri Desktop Shell (top left) — This is the visible application window you interact with. It’s built with Tauri, a framework that creates native desktop apps using web technologies. Inside it, the WebView renders the React-based user interface (the traffic list, panels, buttons, etc.), while the System Tray icon and Native Menu Bar provide standard Mac/Windows app integration.

  • Go Sidecar (center) — This is the engine that does all the heavy lifting. It’s a single program written in Go that contains everything: the MITM Proxy (which intercepts network traffic on port 4545), the REST API (which serves data to the frontend on port 5565), the WebSocket Hub (which pushes real-time updates to the UI), the AI Agent (which connects to language models like Claude or GPT), the Addon Engine (which runs custom JavaScript scripts), the Device Manager (which talks to mobile devices), the SQLite Store (the database where all traffic is saved), the Security Interceptor (which scans for vulnerabilities), and the Frida Manager (which connects to Frida for mobile app manipulation).

  • Browser Extension (bottom left) — An optional Chrome/Firefox extension with three parts: a Service Worker (background process that maintains a WebSocket connection to Ghost), Content Scripts (injected into web pages to observe clicks, inputs, and navigation), and a Popup (the extension’s toolbar UI).

  • External (bottom right) — Things outside Ghost that it communicates with: the Browser or App sending traffic through the proxy, Mobile Devices connected for testing, LLM Providers (like Anthropic’s Claude API or OpenAI) that power the AI agent, and Security Scanners (like Nuclei or sqlmap) that the agent can invoke for vulnerability testing.

The arrows between components show how data flows. For example, when your browser makes a request, it goes through the MITM Proxy, which saves it to the SQLite Store and simultaneously pushes a real-time event through the WebSocket Hub to the WebView, so you see the request appear in your traffic list instantly.

When you double-click Ghost to launch it, here’s exactly what happens behind the scenes, step by step:

What this diagram shows — the full startup sequence in plain language:

  1. Tauri launches the Go engine — The Tauri desktop shell (the native app container) starts first, then spawns the Go sidecar as a child process. Think of Tauri as the car body and Go as the engine — the body starts first, then turns the engine on.

  2. Database initialization — The Go engine opens the SQLite database file in WAL mode (Write-Ahead Logging — a database setting that allows reading and writing at the same time without blocking). If this is the first launch, it runs database migrations to create all the necessary tables. If no capture session exists yet, it creates a default one so traffic has somewhere to go.

  3. Certificate setup — Ghost loads its Certificate Authority (CA) certificate. This is the special certificate that allows Ghost to decrypt HTTPS traffic (see the Certificates page for details). If no CA certificate exists yet (first launch), Ghost generates a new one using ECDSA P-256 cryptography. It also creates a certificate issuer with an LRU cache that can hold 10,000 generated certificates — this means Ghost can handle traffic to up to 10,000 different domains without performance issues.

  4. Loading configuration — The engine loads all user-configured addons (custom scripts), injection rules (JavaScript to inject into web pages), and map rules (traffic redirection and modification rules) from the database.

  5. Manager initialization — The device manager (for connecting to mobile devices via ADB for Android and simctl for iOS) and the Frida manager (for runtime app modification) are created.

  6. Pipeline construction — The interceptor pipeline is assembled — this is the ordered chain of processors that every captured HTTP request passes through (breakpoints → map rules → addons → storage → security analysis).

  7. AI agent setup — The AI agent is created with two separate tool registries: one for QA mode (with tools for test generation, bug reports, etc.) and one for Security mode (with tools for vulnerability testing, attack planning, etc.).

  8. Servers start — The proxy server starts listening on port 4545 (where devices will send their traffic), and the REST API server starts on port 5565 (where the frontend will get its data).

  9. Handshake with Tauri — The Go engine writes a single line of JSON to its standard output containing the port numbers and an authentication token. Tauri reads this line and now knows where to point the user interface.

  10. UI loads — Tauri opens a WebView (an embedded web browser) pointed at the API server’s address, passing the auth token so the frontend can authenticate.

  11. System configuration — If the user previously configured Ghost to act as the system proxy (meaning all traffic on the computer goes through Ghost automatically), it enables that now. It also checks for VPN software and applies workarounds if needed (see VPN Coexistence).

  12. Background workers start — A database maintenance timer starts (runs every 30 minutes to optimize the database file size), and an auto-purge worker starts to clean up old data if configured.

  13. Frontend connects — The React UI fetches initial data (list of sessions, proxy status, configured rules) and establishes a WebSocket connection for real-time updates. From this point on, any new traffic captured by the proxy appears in the UI instantly.

Every HTTP/HTTPS request that flows through Ghost passes through an ordered chain of interceptors — processing stages that can inspect, modify, block, or annotate the traffic. Think of it like an assembly line in a factory, where each station does one specific job before passing the item to the next station.

What this diagram shows: A request enters from the left and passes through five processing stages in order. At each stage, the request can either continue to the next stage (solid arrows moving right) or be diverted (dotted arrows going up or down):

  1. Breakpoints — If a breakpoint rule matches this request, Ghost pauses the request and shows the Breakpoint Editor in the UI. The user can inspect the raw request, modify it, or drop it entirely. If no breakpoint matches, the request passes through instantly.

  2. Map Rules — If a map rule matches, Ghost can redirect the request to a different server (useful for pointing staging traffic to production or vice versa), rewrite the URL path, or return a completely fake “mock” response without ever contacting the real server. This is powerful for testing — you can make your app think an API returned an error to test error handling.

  3. Addons — User-written JavaScript scripts run here. Addons can modify headers, change the body, add tags to the flow for filtering later, drop the request entirely, or return a custom response. This is the most flexible stage.

  4. Storage — The flow (now with all modifications from previous stages applied) is saved to the SQLite database. At this point, the flow gets its unique ID and becomes visible in the traffic list.

  5. Security — In security mode, the security interceptor scans the request and response for common vulnerabilities and misconfigurations (missing security headers, insecure cookies, information leakage, etc.). Any findings are stored separately and linked to this flow.

The pipeline order is deliberate and each position has a specific reason:

PositionInterceptorWhy It’s in This Position
1stBreakpointsMust run first so the user sees the original, unmodified request. If map rules or addons ran first, you’d be debugging already-transformed data, which defeats the purpose of breakpoints.
2ndMap RulesURL rewriting and redirecting need to happen before addons run, because addons may make decisions based on the destination URL. If an addon checks “is this going to api.example.com?”, the URL should already reflect any map rule redirects.
3rdAddonsUser scripts run after breakpoints and map rules but before storage, so they can modify the final state of the flow before it’s persisted. Addons have the most flexibility — they can see changes made by earlier stages and make additional modifications.
4thStorageThe flow is saved to the database after all modifications are applied, so what you see in the traffic list is the final version of the request/response. Storage also assigns the flow’s unique database ID, which later stages need.
5thSecuritySecurity analysis runs last because it needs the flow’s database ID (to link findings to specific flows) and should analyze the final version of the traffic, not an intermediate state. It’s also read-only — it never modifies the flow, only creates findings.

Ghost’s AI agent is more than a simple chatbot. It follows a structured plan-execute-reflect-terminate loop, similar to how a professional penetration tester or QA lead would approach a task: first plan what to do, then execute each step, reflect on results, and decide whether to continue or wrap up.

What this diagram shows — the AI agent’s thinking process:

When you ask the agent a question or give it a task (like “analyze the login flow for security issues”), it doesn’t just fire off a single response. Instead, it goes through a structured cycle:

  1. PLANNER — The agent first creates a plan: a numbered list of steps it will execute. For example: “Step 1: Search traffic for login-related endpoints. Step 2: Analyze authentication headers. Step 3: Check for session token vulnerabilities. Step 4: Generate a findings report.” The plan can be revised mid-execution if the agent discovers something unexpected.

  2. EXECUTOR — The agent works through the plan one step at a time. For each step, it calls the relevant tools — searching traffic, analyzing flows, running security tests, etc. It can execute up to 4 tool calls in parallel for efficiency (for example, searching for multiple endpoints at the same time). If the agent calls present_options, the loop pauses — an interactive choice panel appears in the UI, and the agent waits for the user to select an option before continuing.

  3. REFLECTOR — After completing each step, the agent pauses to assess quality. Did this step produce useful results? Should the plan be adjusted? Is there a pattern forming? This prevents the agent from blindly executing a plan that’s no longer relevant.

  4. TERMINATOR — After reflection, the agent checks six termination signals to decide whether to continue to the next step or stop and produce a final report. This prevents the agent from running forever or wasting resources.

  5. REPORTER — When the agent decides to stop (for any reason), it synthesizes all its findings into a coherent response. This ensures you always get a complete answer, even if the agent was interrupted.

  6. User Steering (dotted arrow) — You can send messages to the agent while it’s running to redirect its focus. For example, if it’s analyzing general security and you say “focus on the payment endpoint”, it receives that guidance mid-execution and adjusts its approach.

The agent has six reasons to stop executing and produce a final report. These are checked in this specific priority order every iteration — the first matching signal wins:

PrioritySignalWhat Triggers ItWhy It Exists
1Plan complete + reflectedAll plan steps are done AND the agent has completed its final quality reflectionThe natural end — the agent finished everything it set out to do and confirmed its work is complete.
2Plan completed + text-onlyPlan status is “completed” and the agent produced a text response with zero tool calls in the last iterationThe agent is writing its final summary — no more tool calls needed.
3Loop detectionThe same tool with the same input (verified by FNV-1a hash) was called 3 or more times within the last 10 tool call recordsPrevents the agent from getting stuck in a retry loop.
4Diminishing returnsAfter iteration 8: the current step is still “in progress” AND the last 6 consecutive tool calls are all the same tool nameThe agent is spinning — calling the same tool over and over without advancing the plan.
5Budget reservationIteration reaches 22 of 25 (reserves the last 3 iterations for writing a final report)Ensures the agent always has room to produce a quality summary rather than being cut off mid-analysis.
6User stopYou click the stop button in the UIThe agent wraps up the current step and writes a summary of what it found so far.

The hard cap is 25 iterations (LLM calls) per run. If none of the above signals trigger and the agent reaches 25, the run ends.

Ghost’s agent has access to 76 tools across QA and Security modes (searching traffic, analyzing flows, sending requests, generating code, running scanners, etc.). Sending all tool definitions to the LLM with every request would be wasteful. Instead, Ghost uses tool routing — it dynamically selects 15-25 relevant tools based on the current plan step’s category:

Plan Step CategoryTools Made AvailableExamples
Reconnaissance (understanding what’s there)Traffic search, session/journey listing, endpoint discovery, WebSocket/console/navigation/storage eventssearch_traffic, find_endpoints, list_sessions, list_ws_messages, list_console_errors
Analysis (deep-diving into specific flows)Flow details, body inspection, regression detection, findings inspectionget_flow, get_flow_body, list_findings
Active testing (probing for vulnerabilities)HTTP sending, request attacker, fuzzing, scanners (nuclei, dalfox, ffuf, sqlmap, katana, etc.), replaysend_http_request, attack_request, fuzz_endpoint, run_nuclei, run_ffuf
Exploitation (proving a vulnerability is real)SQL injection, targeted attacks, manual HTTP, replay, approval gatesrun_sqlmap, attack_request, send_http_request, request_approval
Reporting (summarizing findings)Test generation, bug reports, session reports, API docs, mock servers, file writinggenerate_test, generate_bug_report, generate_api_docs, fs_write

A set of base tools (plan management, core traffic queries, workspace operations) is always available regardless of the current phase. Conditional tools (browser extension, mobile inspector, Frida) are always included if their dependency is connected. If no plan exists yet, the full tool registry is sent so the agent can decide what to plan.

This diagram shows how data moves through Ghost from the moment your device sends a request to the moment you see it in the UI:

What this diagram shows — the journey of a single HTTP request through Ghost:

The system is organized into five layers, read from left to right:

  1. Client Layer (far left) — Where traffic originates. This could be your web browser sending requests through Ghost’s proxy, a mobile app on a connected phone, or the browser extension capturing interactions. All three sources feed into Ghost the same way.

  2. Proxy Layer — Traffic first hits the MITM Proxy (Man-in-the-Middle proxy, listening on port 4545). MITM means Ghost positions itself between your device and the internet so it can see the raw request and response data, even for HTTPS (encrypted) traffic. Next, the Noise Detection system checks whether this is “noise” — repetitive background traffic like analytics pings, health checks, or telemetry that clutters the traffic list without providing useful information. Noise is suppressed (the dotted arrow looping back), while legitimate traffic continues to the Interceptor Pipeline (breakpoints → map rules → addons → storage → security, as described above).

  3. Storage Layer — The pipeline saves each flow to the SQLite database. SQLite is a file-based database — all your captured traffic lives in a single file on your disk. It uses WAL (Write-Ahead Logging) for fast concurrent reads/writes and FTS5 (Full-Text Search version 5) for instant text search across all your captured data.

  4. API Layer — The REST API (port 5565) serves data to the frontend when it asks for it (like “give me the list of flows for this session” or “show me the details of this specific request”). The WebSocket Hub pushes real-time events to the frontend without being asked — when a new flow is captured, it broadcasts a flow.created event so the UI updates instantly.

  5. UI Layer (far right) — The React Frontend renders everything you see and interact with. It receives real-time events via WebSocket (so new traffic appears instantly) and makes REST API queries when you navigate or search. The Tauri Shell manages the desktop window and sends proxy control commands (start/stop) via the REST API.

The key takeaway: traffic flows left-to-right from your device through the proxy, gets filtered for noise, processed by the interceptor pipeline, stored in the database, and pushed in real-time to the UI. The whole journey from “your app sends a request” to “you see it in Ghost” takes milliseconds.

When Ghost is running, three separate processes (programs) are active on your computer:

ProcessBuilt WithWhat It Does
Tauri shellRust (a fast, safe programming language)Manages the application window, native macOS/Windows menu bar, system tray icon, and hosts the WebView (embedded browser) that renders the React UI. Also acts as a safety net that monitors the Go engine (explained below).
Go sidecarGo 1.25 (a programming language designed for networked services)The core engine. Runs the proxy that intercepts traffic, the REST API that serves data, the AI agent that analyzes traffic, the SQLite database that stores everything, and the device manager that talks to phones. All of this lives in a single binary file — one program that does everything.
Browser extensionTypeScript (JavaScript with type safety)Runs inside Chrome or Firefox. Observes user interactions on web pages (clicks, form submissions, navigation), sends them to Ghost for correlation with network traffic, and can perform automated actions or inject JavaScript into pages.

When Tauri starts, it launches the Go sidecar as a child process with the --sidecar flag. The Go engine initializes everything (database, proxy, API, agent) and then writes a single line of JSON to its standard output:

{"api_port": 5565, "proxy_port": 4545, "token": "abc123..."}

Tauri reads this line and now knows two things: what ports to connect to, and what authentication token to use. It opens a WebView (embedded browser) pointed at http://localhost:5565?__ghost_token=abc123..., which loads the React frontend.

Safety Net — Protecting Your Internet Connection

Section titled “Safety Net — Protecting Your Internet Connection”

This is one of Ghost’s most important reliability features. Here’s the problem it solves:

When Ghost is running as your system proxy (meaning all internet traffic on your computer automatically routes through Ghost), what happens if the Go engine crashes? Your traffic would be sent to port 4545 where nothing is listening anymore — effectively killing your internet connection.

Ghost’s Tauri shell solves this with a safety net:

  1. Health monitoring — Tauri pings the Go engine’s health endpoint (/api/v1/proxy/status) every 3 seconds.
  2. Crash detection — If 3 consecutive health checks fail (meaning the engine has been unreachable for at least 9 seconds), and the system proxy was enabled, Tauri assumes the engine has crashed.
  3. Native proxy cleanup — Tauri disables the system proxy directly using operating system commands (bypassing the dead Go engine entirely):
    • On macOS: Runs networksetup commands to remove the proxy setting from all network services
    • On Windows: Writes to the Windows Registry to set ProxyEnable=0
  4. Graceful shutdown — When you close Ghost normally (not a crash), Tauri first disables the system proxy natively (as a safety measure), then asks the Go engine to shut down cleanly, then terminates the process.

This means even in the worst case — the Go engine crashes completely — your internet connection is restored within 9 seconds, automatically, without you needing to do anything.