Skip to content

Get started

How it works

The concepts behind Cloak Proxy, explained: the local proxy, CONNECT tunnels, TLS interception, the root certificate, the macOS proxy, the proxy guard, bypass and DNS capture.

Cloak Proxy is an HTTP proxy that runs on your Mac. Apps send their requests to it instead of straight to the internet, and it forwards them, records each exchange and lets you change them on the way. This page explains the pieces involved, so you know why traffic does or doesn’t show up and what each setting changes.

When Cloak Proxy opens, it starts a proxy server on port 9090. By default it listens on 127.0.0.1, so only programs on this Mac can use it. When you allow other devices to connect, it listens on every network interface (0.0.0.0) instead.

Anything configured to use 127.0.0.1:9090 as its HTTP proxy sends its traffic through Cloak Proxy: the whole Mac (through the macOS proxy settings), a single Terminal, an iPhone on the same Wi-Fi, an Android emulator, or a Docker container.

For each request, Cloak Proxy:

  1. Works out which app sent it. For connections from this Mac it maps the connection’s source port to the process that owns it, and maps helper processes to the app they belong to (so a browser’s helper shows as the browser). Connections from other devices are labeled with the device’s IP address.
  2. Runs the request through the debugging tools you’ve turned on, such as Map Local, Breakpoint or Scripting.
  3. Checks that the host name resolves before connecting, so requests to hosts that don’t exist fail at once instead of waiting for a timeout.
  4. Sends it to the server, using HTTP/2 when the server supports it, and records the response.

Cloak Proxy doesn’t follow redirects or decompress responses on the way through: the app receives exactly what the server sent. The inspector decodes gzip, deflate and Brotli bodies for display.

Plain HTTP requests arrive at the proxy as full URLs (GET http://api.example.com/v1/users). Cloak Proxy reads, records and forwards them directly.

HTTPS works differently. The app first asks the proxy to open a tunnel with a CONNECT api.example.com:443 request, then speaks TLS through that tunnel to the server. A proxy that only relays the tunnel sees the host name and how long the connection stayed open, but not the requests inside it.

What Cloak Proxy does with a tunnel depends on your SSL Proxying rules:

Tunnel What Cloak Proxy does What you see
Port 443, not set up for decryption Connects to the server and relays the encrypted bytes untouched. One CONNECT row with a closed lock. Click it for buttons that turn on decryption.
Set up for decryption (any port) Answers the CONNECT, then decrypts the TLS connection (see below). Every request inside the tunnel as its own row, with a green open lock.
Another port, not set up for decryption Answers the CONNECT and looks at the first bytes. TLS is relayed untouched; plain HTTP inside the tunnel is read and recorded. A locked row for TLS, or readable http:// rows for plain HTTP.

A tunnel Cloak Proxy relayed without reading it. The buttons turn on decryption for the host or for the whole app.

  1. The CONNECT request that opened the tunnel
  2. The app that opened it
  3. Decrypt this host only
  4. Decrypt every host this app connects to
The inspector for a CONNECT row to www.apple.com from Google Chrome, explaining the HTTPS connection was passed through encrypted, with buttons to enable SSL Proxying for the host or for the app

If Cloak Proxy can’t reach the server, the tunnel row shows as failed with the reason, and the app gets a 502 Bad Gateway. See Failed requests and tunnels.

To read HTTPS, Cloak Proxy sits in the middle of the TLS connection. This is often called a man-in-the-middle (MITM) proxy.

  1. The app opens a tunnel to api.example.com:443 and starts a TLS handshake.

  2. Cloak Proxy answers the handshake itself, presenting a certificate for api.example.com that it has just signed with its own root certificate.

  3. The app accepts that certificate only if it trusts Cloak Proxy’s root certificate. That’s why you click Install & Trust….

  4. Cloak Proxy now reads each request in plain text, runs it through your tools, and sends it to the real server over a separate TLS connection that it opens itself. That connection checks the server’s real certificate as usual.

  5. The response travels back the same way, and both sides are recorded.

With Offer HTTP/2 to apps on decrypted connections on (the default), apps that support HTTP/2 use it on their side of the decrypted connection, and Cloak Proxy handles each stream as a separate request. See Offer HTTP/2 to apps.

The root certificate (a certificate authority, or CA) is what makes interception possible. Cloak Proxy generates one on your Mac the first time it opens:

Property Value
Name Cloak Proxy CA ( your Mac’s name, the date )
Key ECDSA P-256
Valid for 10 years
Files cloak-proxy-ca.pem and cloak-proxy-ca-key.pem in ~/Library/Application Support/CloakProxy
Trust Added to your login keychain as a trusted root when you click Install & Trust…

For each host it decrypts, Cloak Proxy signs a host certificate valid for one year (Apple rejects host certificates valid for longer than 825 days) and reuses it for that host.

macOS has system-wide proxy settings for each network service (Wi-Fi, Ethernet and so on). Apps that use Apple’s networking, including Safari, Chrome and most Mac apps, follow them.

When you turn on macOS traffic, Cloak Proxy:

  1. Saves a snapshot of each enabled network service’s HTTP proxy, HTTPS proxy and bypass list.
  2. Sets the HTTP and HTTPS proxy of every enabled network service to 127.0.0.1 and Cloak Proxy’s port, and writes your bypass list.
  3. Restores the snapshot when you turn macOS traffic off or quit. If you had no proxy before, it turns the proxy settings off.

The snapshot is stored in Cloak Proxy’s preferences, so it survives a crash. See Capture macOS traffic.

While the macOS proxy points at Cloak Proxy, every app that follows it depends on Cloak Proxy being there. If Cloak Proxy stopped without restoring the settings, those apps would lose their connection to the internet.

Cloak Proxy protects you in three ways:

  • Normal quit. Quitting restores the snapshot before the app exits.
  • Signals. If the process receives SIGTERM, SIGINT or SIGHUP (for example kill, or Ctrl C in a terminal that launched it), it restores the settings before exiting.
  • The proxy guard. When the macOS proxy is on, Cloak Proxy starts a small helper, cloakctl proxy-guard, in its own session. It waits for Cloak Proxy to exit. If Cloak Proxy disappears without quitting (Force Quit or a crash), the guard waits two seconds, checks that the macOS proxy still points at Cloak Proxy’s port and that nothing is listening there anymore, and restores your saved settings.

The guard does nothing if you’ve already reopened Cloak Proxy or if the settings no longer point at it. It records what it did in ~/Library/Logs/CloakProxy/cloak-proxy.log.

The bypass list names hosts that should skip the proxy entirely when the macOS proxy is on. macOS sends requests for them straight to the network, so Cloak Proxy never sees them. By default it holds localhost, *.local and 169.254/16.

The bypass list is part of the macOS proxy settings, so it only affects apps that follow the macOS proxy. See Exclude hosts with the bypass list.

DNS capture for apps that ignore the proxy

Section titled “DNS capture for apps that ignore the proxy”

Some apps never use the macOS proxy: apps with their own network stack (gRPC, Network.framework), and some payment and security SDKs. Cloak Proxy notices them by looking for direct connections to the internet and lists them under Not Using the Proxy in the sidebar.

To capture such an app, Cloak Proxy takes over the DNS lookups for its domains:

  1. For each domain you choose, it adds a file to /etc/resolver (macOS asks for your password). The file tells macOS to ask Cloak Proxy’s own resolver, on 127.0.0.1 port 53535, about that domain and its subdomains.

  2. When an app looks up a captured name, the resolver asks your network’s real DNS servers for the real address, remembers it, and answers 127.0.0.1. IPv6 lookups for captured names get an empty answer, so apps connect over IPv4.

  3. The app connects to 127.0.0.1 on port 443 or 80. Cloak Proxy accepts the connection, reads the host name from the TLS handshake (SNI) or the Host header, and handles it like a tunnel to the real address. Captured domains are always decrypted.

  4. While Cloak Proxy is closed, a background helper started at login answers the same lookups with the real addresses, so the app keeps working.

See Apps that ignore the proxy.

Everything happens on your Mac. Cloak Proxy has no account and no server of its own: captured traffic stays in memory until you save or export it, and the only thing that leaves your Mac is the traffic you send through it to its real destination, plus anything you choose to publish, such as a Gist. See Security and privacy.