How-to guide · Trust a CA
How to trust a private root CA on macOS
In one sentence
Your Mac, or every managed Mac, trusts your organisation's private root CA in the System keychain, and you know which apps need their own setting.
- Task
- Trust a CA
- Platforms
- macOS
- Level
- Practitioner · 5 steps
On this page
Before you start
- The root certificate of your private CA as a
.cer,.crtor.pemfile (DER or PEM). Only the public certificate, never a.p12or a private key. - Its SHA-256 fingerprint, from a channel you trust (your PKI team’s HTTPS intranet page, a signed ticket), not from the message that carried the file.
- An administrator account on the Mac. macOS asks for an administrator’s password to change trust;
sudoalone is not enough. - For a fleet: a device management (MDM) service.
Why it matters: a trusted root can vouch for any name in Safari, Chrome and every app that asks macOS to check certificates. Add only roots your organisation controls.
Steps
1. Check the file before you trust it
Compute the fingerprint and compare it with the published value. Hashing the DER form gives the certificate’s fingerprint, and works with the LibreSSL openssl that ships with macOS:
openssl x509 -in corp-root.crt -outform DER | shasum -a 256
bc02a4f5dc68b3fdcdc478030e308cb59d6da0845aa0b4333660788e96c22e01 -
Then check that it really is a root CA: subject and issuer are the same, and the CA flag is set. With OpenSSL 3 (for example from Homebrew) the output for our throwaway test root is:
openssl x509 -in corp-root.crt -noout -subject -issuer -enddate -ext basicConstraints
subject=C=BE, O=Example Corp, CN=Example Corp Root CA
issuer=C=BE, O=Example Corp, CN=Example Corp Root CA
notAfter=Oct 17 01:43:50 2036 GMT
X509v3 Basic Constraints: critical
CA:TRUE
The decoder below shows the same fields, in your browser. Paste certificates only, never a private key.
2. Add it with Keychain Access
This follows Apple’s Keychain Access guide:
- Open Keychain Access (search for it with Spotlight).
- Select the System keychain, so the root applies to every account on the Mac. The login keychain covers only you.
- Drag the certificate file onto the Keychain Access window, and type an administrator’s name and password.
- Double-click the certificate, click the arrow next to Trust, and set When using this certificate to Always Trust (changing trust settings). Close the window and enter the password again.
Adding the certificate is not enough on its own: until its trust setting says Always Trust, macOS treats it as an ordinary, untrusted certificate.
3. Or add it from the Terminal
The security command adds the certificate and its trust setting in one step. -d writes the admin trust settings (for all users), -r trustRoot marks it as a trusted root, and -k names the keychain:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain corp-root.crt
Since macOS Big Sur, this still opens a dialog for an administrator’s password. Apple’s Big Sur release notes say “Running as the root user alone is no longer sufficient to modify certificate trust”. So the command cannot run unattended from a script; use MDM for that (step 4).
For your own account only, leave out sudo and -d and name your login keychain:
security add-trusted-cert -r trustRoot -k ~/Library/Keychains/login.keychain-db corp-root.crt
4. Or roll it out with MDM
On managed Macs, put the root in a Certificates payload of a configuration profile. Apple’s Certificates payload settings say a certificate gets full trust automatically when it is “Automatically installed from a supported device management service”, or by a payload in an MDM enrollment profile. Apple also advises: “avoid having users manually install certificates”.
The same profile works for iPhone and iPad. A root that a user installs by hand there also needs Settings > General > About > Certificate Trust Settings (Apple).
5. Point the apps that ignore the keychain
| Program | Uses the macOS trust settings? | What to do |
|---|---|---|
| Safari, Mail, apps using Apple’s networking | Yes | Nothing |
| Chrome, Edge | Yes: roots in the System and login keychains marked Always Trust (Chrome Root Store FAQ) | Restart the browser |
| Firefox | Yes, by default since Firefox 120 (Mozilla) | Restart Firefox |
| Node.js, npm | No | node --use-system-ca reads the keychain (Node.js), or NODE_EXTRA_CA_CERTS: see Python, Node.js and npm |
| pip 24.2 and later | Yes, in addition to its own bundle | Nothing |
Python requests, python.org’s Python |
No, they use the certifi bundle | See Python, Node.js and npm |
| Java | No, it uses cacerts |
See Java trust stores |
| Homebrew’s OpenSSL and the tools built on it | Only from a snapshot | After adding the root to the System keychain, run brew postinstall ca-certificates to rebuild Homebrew’s bundle |
| Docker containers | No, they are Linux | See Linux |
Check it worked
List the admin trust settings. Your root should appear with its name:
security dump-trust-settings -d
Confirm which certificate is in the System keychain, by fingerprint:
security find-certificate -a -c "Example Corp Root CA" -Z /Library/Keychains/System.keychain | grep SHA-256
Then let macOS’s own trust evaluation check a real internal server. Given a URL, security verify-cert connects and checks the server’s chain against the SSL server policy (security(1)):
security verify-cert https://intranet.example.com/
A successful verification means the chain reaches your root. Finally, open the site in Safari and in Chrome.
If something goes wrong
- Safari or Chrome still show
NET::ERR_CERT_AUTHORITY_INVALID. The certificate is in a keychain but not set to Always Trust, it went to the login keychain of another user, or the server’s chain ends at a different root. Compare the issuer in the browser’s certificate viewer with your file. - Firefox says
SEC_ERROR_UNKNOWN_ISSUER. Check thatsecurity.enterprise_roots.enabledistrueinabout:config, or that your Firefox policy does not turn it off. - The browser works, but the command line fails with
self-signed certificate in certificate chainorCERTIFICATE_VERIFY_FAILED. That tool reads its own bundle: see step 5. - The command line works, but some clients report “unable to get local issuer certificate”. The server leaves out its intermediate. Fix the server: build the full chain file and see verify error 21.
add-trusted-certfails in a script or over SSH. That is the Big Sur change in step 3: it needs an administrator to authenticate in a dialog. Use an MDM profile.
Why this works
macOS keeps certificates in keychains and decides trust separately, through trust settings in a user, admin or system domain. When an app asks macOS to check a server, it builds a certificate chain and accepts it only if it ends at a certificate whose trust setting says Always Trust. Being self-signed does not make your root trustworthy; the trust setting does (Who do we trust?). How the chain is checked is in Certificate chains and path validation, and how to design a private CA worth trusting is in A CA of your own.
Go deeper
- Keychain Access: add certificates and change trust settings: Apple’s step-by-step guides.
- security(1) manual:
add-trusted-cert,remove-trusted-cert,dump-trust-settingsandverify-cert, from Apple’s open-source Security project. - macOS Big Sur 11.0.1 release notes: why changing trust needs an administrator’s password.
- Certificates payload settings: deploying roots with MDM.
- Chrome Root Store FAQ: which keychain settings Chrome honours.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.