A technical deep-dive into how Trace intercepts and decrypts HTTPS traffic using an on-device certificate authority, certificate pinning detection, and transparent proxying.
Understanding how Trace intercepts HTTPS traffic is essential for effective debugging and understanding when certificate pinning will prevent inspection. This post explains the technical details of TLS man-in-the-middle (MITM) inspection.
The problem: HTTPS is encrypted
When your app makes an HTTPS request, the traffic is encrypted end-to-end between your app and the server. This is great for security but problematic for debugging—you can't see request or response bodies without breaking the encryption.
Traditional network tools use packet capture (like tcpdump or Wireshark), but these only show encrypted bytes. To inspect HTTPS, you need to decrypt it.
How MITM works
Man-in-the-middle (MITM) inspection works by inserting a proxy between your app and the destination server. The proxy:
Accepts the TLS connection from your app
Establishes a separate TLS connection to the actual server
Decrypts traffic from your app, inspects it, then re-encrypts and forwards it to the server
Does the reverse for responses
The challenge is getting your app to trust the proxy's certificate instead of rejecting it as invalid.
Trace's certificate authority
Trace implements an on-device certificate authority (CA) that generates certificates dynamically:
Root CA generation
On first launch, Trace generates a root CA certificate and private key. This root CA is stored securely in the App Group container. The root certificate is what you install in iOS Settings > General > VPN & Device Management.
Dynamic certificate generation
When your app connects to api.example.com, Trace:
Checks if a certificate for api.example.com already exists in its cache
If not, generates a new certificate signed by the Trace root CA
The generated certificate includes the correct Subject Alternative Name (SAN) for api.example.com
Presents this certificate to your app during the TLS handshake
Because your device trusts the Trace root CA, it trusts any certificate signed by that CA—including the dynamically generated one for api.example.com.
Certificate caching
Generated certificates are cached to avoid regenerating them on every connection. The cache is stored in the App Group container and persists across app launches.
The TLS handshake
Here's what happens when your app makes an HTTPS request through Trace:
Diagram
Both connections use real TLS. Trace isn't "breaking" encryption—it's acting as a trusted intermediary.
Certificate pinning
Certificate pinning is a technique where apps refuse to trust certificates unless they match a specific expected certificate or public key. This breaks MITM inspection intentionally.
How pinning works
Apps can pin in several ways:
Certificate pinning: Only trust if the exact certificate matches
Public key pinning: Only trust if the public key matches
CA pinning: Only trust certificates signed by specific CAs
If an app pins to the real server's certificate, it will reject Trace's dynamically generated certificate even though iOS trusts it at the system level.
Detecting pinning in Trace
Trace detects certificate pinning by monitoring connection failures. If a TLS handshake completes successfully but the app immediately closes the connection, Trace flags it as likely certificate pinning.
You'll see a warning icon on affected requests in the UI.
Security implications
Installing the Trace root CA means your device trusts any certificate signed by it. Never
install root CAs from untrusted sources. Trace's root CA is generated on your device and never
leaves it.
When you're finished debugging, you can remove the root CA from Settings. Trace will continue to
capture traffic, but HTTPS inspection will stop working.
The root CA private key is stored in the App Group container with standard iOS app sandbox
protections. Other apps cannot access it.
Implementation details
Trace's MITM implementation uses:
Network.framework: For TLS connection handling and certificate validation
Security.framework: For certificate generation and trust evaluation
CommonCrypto: For cryptographic operations
All certificate generation happens synchronously during the TLS handshake to avoid race conditions.
When MITM fails
MITM inspection can fail in several scenarios:
The app explicitly validates the server's certificate or public key and rejects the
Trace-generated certificate. This is common in banking apps, social media apps, and
security-conscious applications.
The user hasn't enabled "Full Trust" for the Trace root CA in Settings → General → About →
Certificate Trust Settings. Without this, iOS won't trust certificates signed by Trace.
The server requires the client to present a certificate (mutual TLS). Trace can't automatically
forward client certificates without additional configuration.
Apps using non-standard TLS libraries or custom certificate validation logic may not respect
system trust settings.
Trace handles these gracefully by capturing what it can (HTTP headers, connection metadata) without failing the request.
Conclusion
TLS MITM is a powerful debugging tool when used responsibly. Understanding how it works helps you debug effectively and recognize when certificate pinning or other protections prevent inspection.