← Back to Blog

Trust a local root certificate in iOS Simulator with simctl

Technical note Published July 6, 2026 4 min read
iOSSimulatorCertificatesCapacitorIonicDebugging

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;
  • NSURLErrorDomain with 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 .p12 imported with SecPKCS12Import, 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 help locally to see the available keychain actions. The command lists add-root-cert, add-cert, and reset.
  • Capacitor live reload loads a WebView from a development URL during local development.