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
System Overview
Rockxy is split into three trust and execution domains:
- UI + orchestration layer — SwiftUI/AppKit windows, inspectors, menus, and the
MainContentCoordinator - Proxy/runtime layer — SwiftNIO channel handlers, certificate issuance, request mutation, storage, and plugins
- 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
| Layer | Main Types | Responsibility |
|---|---|---|
| Presentation | MainContentCoordinator, ContentView, inspector/request-list/sidebar views | Holds user-facing state, routes commands, binds proxy/log data into SwiftUI/AppKit |
| Capture / transport | ProxyServer, HTTPProxyHandler, TLSInterceptHandler, HTTPSProxyRelayHandler | Accepts proxy traffic, performs CONNECT handling, MITM TLS interception, and upstream forwarding |
| Mutation / policy | RuleEngine, BreakpointRequestBuilder, AllowListManager, NoCacheHeaderMutator | Applies request/response rules and current debugging policy before forwarding or storing |
| Certificate / trust | CertificateManager, RootCAGenerator, HostCertGenerator, CertificateStore, KeychainHelper | Generates and persists the root CA, caches host certs, validates trust state |
| Storage / session | TrafficSessionManager, LogCaptureEngine, SessionStore, in-memory buffers | Buffers live data, persists selected state to SQLite, and batches updates to the UI |
| Observability / analysis | GraphQL detection, content-type detection, log correlation | Enriches captured traffic after or alongside transport processing |
| Privileged system integration | HelperConnection, RockxyHelperTool, shared XPC protocol | Applies 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.
| Package | Version | Purpose |
|---|---|---|
| apple/swift-nio | 2.76+ | Non-blocking event loop for the proxy server |
| apple/swift-nio-ssl | 2.29+ | TLS handling for HTTPS interception |
| apple/swift-certificates | 1.7+ | X.509 certificate generation (root CA + per-host) |
| apple/swift-crypto | 3.10+ | Cryptographic primitives |
| stephencelis/SQLite.swift | 0.15+ | SQLite wrapper for session and log persistence |
Project Structure
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 bootstrapCertificateManager— manages root CA and per-host certificate cache (~1,000 entries LRU)LogCaptureEngine— captures logs from multiple sources concurrentlyInMemorySessionBuffer— 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 inspectorExporterPlugin— 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
| Data | Storage | Implementation |
|---|---|---|
| Live traffic | Batched in-memory workspace state (50k default live cap) | TrafficSessionManager + MainContentCoordinator |
| Saved sessions | SQLite | SessionStore |
| Root CA key | macOS Keychain | KeychainHelper |
| Rules | JSON file | RuleStore |
| Large bodies (>1MB) | Disk files | ~/Library/Application Support/com.amunx.rockxy.community/bodies/ for the Community build |
| Log entries | SQLite | SessionStore (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:
NSXPCConnectionwith 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.