architecture.mdx

May 17, 2026 · View on GitHub

Tech Stack

Rockxy is a native macOS application built with:

  • SwiftUI + AppKit hybrid UI (NSTableView for high-volume request lists, SwiftUI for everything else)
  • Swift Concurrency — actors for thread-safe proxy, storage, and log engines
  • SwiftNIO — non-blocking event-driven proxy server
  • swift-certificates — X.509 certificate generation for HTTPS interception
  • SQLite.swift — session and log persistence
  • macOS 14.0+, Swift 5.9
Rockxy is 100% native — no Electron, no web views, no embedded browser engines. Every pixel is rendered by AppKit or SwiftUI.

System Overview

Rockxy is split into three trust and execution domains:

  1. UI + orchestration layer — SwiftUI/AppKit windows, inspectors, menus, and the MainContentCoordinator
  2. Proxy/runtime layer — SwiftNIO channel handlers, certificate issuance, request mutation, storage, and plugins
  3. Privileged helper layer — a separate launchd daemon for system-level proxy and certificate operations requiring elevated privileges

The design goal is to keep packet processing off the main thread, keep privileged operations outside the app process, and keep user-facing state synchronized through explicit actor or @MainActor boundaries.

Component Map

flowchart TB
    subgraph UI["UI Process: Rockxy.app"]
        Menus["Menus / Commands"]
        Windows["SwiftUI + AppKit Windows"]
        Coordinator["MainContentCoordinator (@MainActor)"]
        Workspace["Workspace / Request List / Inspector"]
    end

    subgraph Runtime["Runtime Services"]
        Proxy["ProxyServer (actor)"]
        Traffic["TrafficSessionManager (actor)"]
        LogMgr["LogCaptureEngine (actor)"]
        Cert["CertificateManager (actor)"]
        Rules["RuleEngine"]
        Plugins["ScriptPluginManager"]
        Storage["SessionStore + InMemory Buffers"]
    end

    HelperClient["HelperConnection (@MainActor)"]

    subgraph Privileged["Privileged Domain"]
        Helper["RockxyHelperTool (launchd daemon)"]
        System["macOS Network / Keychain / Trust Settings"]
    end

    Windows --> Coordinator
    Menus --> Coordinator
    Coordinator --> Workspace
    Coordinator --> Proxy
    Coordinator --> Traffic
    Coordinator --> LogMgr
    Coordinator --> Storage
    Proxy --> Rules
    Proxy --> Plugins
    Proxy --> Cert
    Proxy --> Traffic
    Traffic --> Coordinator
    LogMgr --> Coordinator
    Cert --> HelperClient
    HelperClient --> Helper
    Helper --> System

Runtime Layers

LayerMain TypesResponsibility
PresentationMainContentCoordinator, ContentView, inspector/request-list/sidebar viewsHolds user-facing state, routes commands, binds proxy/log data into SwiftUI/AppKit
Capture / transportProxyServer, HTTPProxyHandler, TLSInterceptHandler, HTTPSProxyRelayHandlerAccepts proxy traffic, performs CONNECT handling, MITM TLS interception, and upstream forwarding
Mutation / policyRuleEngine, BreakpointRequestBuilder, AllowListManager, NoCacheHeaderMutatorApplies request/response rules and current debugging policy before forwarding or storing
Certificate / trustCertificateManager, RootCAGenerator, HostCertGenerator, CertificateStore, KeychainHelperGenerates and persists the root CA, caches host certs, validates trust state
Storage / sessionTrafficSessionManager, LogCaptureEngine, SessionStore, in-memory buffersBuffers live data, persists selected state to SQLite, and batches updates to the UI
Observability / analysisGraphQL detection, content-type detection, log correlationEnriches captured traffic after or alongside transport processing
Privileged system integrationHelperConnection, RockxyHelperTool, shared XPC protocolApplies system proxy settings and privileged certificate operations with explicit trust checks

SPM Dependencies

All dependencies are managed via Xcode's SPM integration — there is no top-level Package.swift.

PackageVersionPurpose
apple/swift-nio2.76+Non-blocking event loop for the proxy server
apple/swift-nio-ssl2.29+TLS handling for HTTPS interception
apple/swift-certificates1.7+X.509 certificate generation (root CA + per-host)
apple/swift-crypto3.10+Cryptographic primitives
stephencelis/SQLite.swift0.15+SQLite wrapper for session and log persistence

Project Structure

- Rockxy/ - Core/ - ProxyEngine/ — SwiftNIO HTTP/HTTPS proxy server, channel handlers - Certificate/ — Root CA generation, per-host certs, keychain integration - RuleEngine/ — Rule matching and actions (block, map, throttle, breakpoint) - LogEngine/ — OSLog capture, stdout/stderr, custom log sources - TrafficCapture/ — System proxy manager, session manager, request replay - Storage/ — SQLite persistence, in-memory buffers, settings - Detection/ — GraphQL detector, content type detection, API grouping - Plugins/ — Plugin manager, built-in inspectors and exporters - Services/Infrastructure/ — Window management, notifications - Utilities/ — Body decoder, size and duration formatters - Models/ - Network/ — HTTPTransaction, Request, Response, WebSocket frames - Log/ — LogEntry, LogLevel, LogSource - Rules/ — ProxyRule, RuleAction - Settings/ — AppSettings - UI/ — SidebarItem, InspectorTab, FilterCriteria - Views/ - Main/ — ContentView, Coordinator + Extensions/ - Sidebar/ - RequestList/ - Inspector/ — 8 inspector tab views - Logs/ - Timeline/ - Rules/ - Settings/ - Toolbar/ - Components/ - Extensions/ - Theme/

Design Patterns

Coordinator Pattern

MainContentCoordinator is the central state coordinator — marked @MainActor @Observable and split across extension files to stay within SwiftLint's file length limits:

// MainContentCoordinator.swift — core state
@MainActor @Observable
final class MainContentCoordinator {
    var selectedTransaction: HTTPTransaction?
    var transactions: [HTTPTransaction] = []
    var logEntries: [LogEntry] = []
    var isProxyRunning = false
    var isRecording = false
}

// MainContentCoordinator+ProxyControl.swift
extension MainContentCoordinator {
    func startProxy() async throws { ... }
    func stopProxy() async { ... }
}

// MainContentCoordinator+Filtering.swift
extension MainContentCoordinator {
    func applyFilter(_ criteria: FilterCriteria) { ... }
}

When adding new coordinator functionality, create a new extension file (e.g., MainContentCoordinator+NewFeature.swift) rather than growing an existing file.

Actor Isolation

All engines that handle concurrent data use Swift actors:

  • ProxyServer — owns the NIO event loop and server bootstrap
  • CertificateManager — manages root CA and per-host certificate cache (~1,000 entries LRU)
  • LogCaptureEngine — captures logs from multiple sources concurrently
  • InMemorySessionBuffer — thread-safe ring buffer for active transactions

Cross-isolation calls use async/await:

let certificate = await certificateManager.certificate(forHost: hostname)
await sessionBuffer.append(transaction)

Protocol-Oriented Plugins

Rockxy defines protocols for extensibility:

  • InspectorPlugin — adds custom tabs to the request inspector
  • ExporterPlugin — exports sessions in custom formats (HAR, cURL, etc.)
  • ProtocolHandler — handles application-layer protocols beyond HTTP

Plugins register with PluginManager and are discovered at launch.

Proxy Request Lifecycle

sequenceDiagram
    participant Client
    participant NIO as ProxyServer / NIO Pipeline
    participant HTTP as HTTPProxyHandler
    participant TLS as TLSInterceptHandler
    participant HTTPS as HTTPSProxyRelayHandler
    participant Rules as RuleEngine
    participant Plugins as ScriptPluginManager
    participant Traffic as TrafficSessionManager
    participant UI as MainContentCoordinator
    participant Upstream

    Client->>NIO: TCP connection to local proxy
    NIO->>HTTP: HTTP request or CONNECT tunnel

    alt Plain HTTP
        HTTP->>Rules: evaluate rules
        Rules-->>HTTP: action / no action
        HTTP->>Plugins: optional request hooks
        Plugins-->>HTTP: modified request
        HTTP->>Upstream: forward cleartext HTTP
        Upstream-->>HTTP: response
        HTTP-->>Traffic: completed transaction
    else HTTPS via CONNECT
        HTTP->>Client: 200 Connection Established
        HTTP->>TLS: hand off channel
        TLS->>TLS: generate host cert from root CA
        TLS->>Client: terminate client TLS
        TLS->>HTTPS: decrypted HTTP pipeline
        HTTPS->>Rules: evaluate rules
        Rules-->>HTTPS: action / no action
        HTTPS->>Plugins: optional request hooks
        Plugins-->>HTTPS: modified request
        HTTPS->>Upstream: TLS client connection to real host
        Upstream-->>HTTPS: decrypted response
        HTTPS-->>Traffic: completed transaction
    end

    Traffic-->>UI: batched updates

HTTP vs HTTPS Flow

flowchart LR
    A["Inbound client request"] --> B{"CONNECT tunnel?"}
    B -- No --> C["HTTPProxyHandler"]
    C --> D["RuleEngine + plugins"]
    D --> E["Forward to upstream over HTTP"]
    E --> F["Capture response + timings"]

    B -- Yes --> G["Reply 200 Connection Established"]
    G --> H["TLSInterceptHandler"]
    H --> I["Generate / reuse per-host leaf cert"]
    I --> J["Terminate client TLS"]
    J --> K["HTTPSProxyRelayHandler"]
    K --> L["RuleEngine + plugins"]
    L --> M["Forward to upstream over TLS"]
    M --> N["Capture response + timings"]

Data Flow

Network Traffic

flowchart LR
    A["ProxyServer\n(NIO thread)"] --> B["TrafficSessionManager\n(actor)"]
    B -->|"batched every 100ms\nor 50 transactions"| C["MainContentCoordinator\n(@MainActor)"]
    C --> D["SwiftUI Views"]

Log Capture

flowchart LR
    A["LogCaptureEngine\n(actor)"] --> B["MainContentCoordinator\n(@MainActor)"]
    B --> C["LogStreamView\n(SwiftUI)"]

Proxy Pipeline

The SwiftNIO channel pipeline processes each connection through a series of handlers:

flowchart LR
    A["HTTPProxyHandler\n(HTTP parsing + routing)"] --> B["TLSInterceptHandler\n(CONNECT tunnel + MITM)"]
    B --> C["WebSocketFrameHandler\n(WebSocket upgrade detection)"]
  • HTTPProxyHandler — parses incoming HTTP requests, applies rule engine, routes to upstream
  • TLSInterceptHandler — intercepts CONNECT requests, generates per-host certificates on the fly, establishes TLS tunnel
  • WebSocketFrameHandler — detects WebSocket upgrades and captures individual frames

Storage Architecture

DataStorageImplementation
Live trafficBatched in-memory workspace state (50k default live cap)TrafficSessionManager + MainContentCoordinator
Saved sessionsSQLiteSessionStore
Root CA keymacOS KeychainKeychainHelper
RulesJSON fileRuleStore
Large bodies (>1MB)Disk files~/Library/Application Support/com.amunx.rockxy.community/bodies/ for the Community build
Log entriesSQLiteSessionStore (log_entries table)

Privileged Helper & Security

Rockxy uses a privileged helper daemon (RockxyHelperTool) registered via SMAppService.daemon() for password-free system proxy configuration. The helper runs as root and communicates with the app over XPC.

Security model:

  • NSXPCConnection with code-signing requirements
  • Certificate-chain comparison via ConnectionValidator (defense-in-depth beyond bundle ID)
  • Local Xcode ad-hoc helper repair is limited to DerivedData build products
  • Rate limiting on state-changing operations
  • Port range validation (1024-65535)

Resilience features:

  • Proxy backup/restore — original proxy settings saved to plist before override, auto-restored on helper restart within 24 hours
  • Emergency cleanup — proxy settings restored on SIGTERM, SIGINT, XPC invalidation, and applicationWillTerminate
  • Owner PID watchdog — detects when the app process exits unexpectedly
  • SOCKS proxy backup — backs up and restores SOCKS proxy settings alongside HTTP/HTTPS
  • Stale helper recovery — detects and recovers from stale helper state after crashes

For vulnerability reporting, see SECURITY.md.

Next Steps

Security boundaries, XPC trust model, and certificate trust Why SwiftNIO, NSTableView, actors, and the helper daemon SwiftLint rules, formatting standards, and naming conventions