Trust a local root certificate in iOS Simulator with simctl
TLDR
If iOS Simulator needs to trust a local or internal root CA, add it with
simctl:
xcrun simctl keychain booted add-root-cert ./local-root-ca.pem
For a specific simulator, replace booted with its UDID:
xcrun simctl keychain <simulator-udid> add-root-cert ./local-root-ca.pem
Use this when a development app needs HTTPS, but the certificate chain is signed by a local, private, or infrastructure-specific CA.
When this helps
Capacitor live reload is a common case. The app can load from an external development URL, but your web layer, backend, proxy, secure-context APIs, or infrastructure may still require HTTPS.
You can drag a certificate into Simulator manually. The CLI version is useful once simulators start getting erased, reset, recreated, or replaced after Xcode updates.
Other cases:
- Debugging a local HTTPS dev server from a WebView.
- Testing a private API, development server, or MQTT endpoint signed by an internal CA.
- Intercepting HTTPS traffic from iOS Simulator with tools such as Charles, Proxyman, or mitmproxy.
- Testing flows where certificate trust is part of the real environment.
Be precise about the boundary: trusting a root CA and presenting a client
certificate are different problems. In mutual-TLS setups, the app may also need
a client identity, often a .p12 file. This command only helps with the trust
side.
Why not skip SSL checks?
Disabling certificate validation can be tempting when you just want live reload
or a local dev server to work. For Capacitor,
@jcesarmobile/ssl-skip does
exactly that during development.
The plugin itself warns that it is development-only and should be removed before submitting an app. I would still avoid making SSL skipping part of the normal workflow: it is too easy to keep the wrong flag, run the wrong build, or normalize bypassing the behavior you are trying to test.
Adding the root CA is also development-only, but the app still validates certificates. The simulator simply knows about your development CA.
Add the root certificate
Make sure the file is the root CA certificate, not just the server’s leaf certificate:
openssl x509 \
-in ./local-root-ca.pem \
-noout \
-subject \
-issuer \
-dates
Add it to the booted simulator:
xcrun simctl keychain booted add-root-cert ./local-root-ca.pem
If you have more than one simulator running, use the exact simulator UDID:
xcrun simctl list devices booted
Then:
xcrun simctl keychain <simulator-udid> add-root-cert ./local-root-ca.pem
Useful simctl keychain actions:
add-root-cert [path]: add a certificate to the trusted root store.add-cert [path]: add a certificate to the keychain.reset: reset the keychain.
What the failure looks like
In a native or Capacitor app, the useful signal is often in the Xcode console. The UI may show a blank screen, a generic network error, or a failed WebView load, while the console mentions:
- the certificate is not trusted;
- the certificate for this server is invalid;
NSURLErrorDomainwith a secure connection or server trust failure;- a WebView or native HTTP client error mentioning SSL, TLS, or certificate validation.
If adding the root CA does not change the error, the root CA may not be the problem. Check the leaf certificate, intermediate chain, hostname, and platform TLS requirements.
Caveats
- Simulator only: this does not install trust on a physical iPhone. For a real device, use a certificate profile, Apple Configurator, or Mobile Device Management. Manual root certificates also need full trust enabled in Settings (Apple profile docs). Jailbreaking just to work around certificate trust is usually the wrong direction.
- HTTPS still has to be HTTPS. This does not make HTTP acceptable when the app or platform requires HTTPS (Ionic HTTPS live reload note).
- It does not bypass certificate pinning, fix an expired or malformed server certificate, or make a leaf certificate behave like a root CA.
- Mutual TLS needs more than trust. If the app must present a client
certificate, you need an identity with a private key, usually a
.p12imported withSecPKCS12Import, then passed into the TLS configuration while still validating the server chain. - The server certificate still needs to match the hostname, include Subject Alternative Name, and be within its validity window. For self-signed or private TLS server certificates, keep the leaf validity at 825 days or fewer (Apple TLS requirements).
Cleanup
To reset the simulator keychain:
xcrun simctl keychain booted reset
Treat this as broad cleanup. If the simulator is disposable, erasing the simulator is often clearer.
References
- Run
xcrun simctl keychain helplocally to see the available keychain actions. The command listsadd-root-cert,add-cert, andreset. - Capacitor live reload loads a WebView from a development URL during local development.