Programmatically installing a Root CA with "Always Trust" via LaunchDaemon for DLP agent

Hello,

I am working on a DLP (Data Leak Prevention) agent which must programmatically install our custom Root CA certificate into the System Keychain with the "Always Trust" policy. This is required for our network inspection module.

The installation process is currently handled by a LaunchDaemon. I am using the following command:

security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <path to certificate>

The certificate is successfully added to the System Keychain, but the "Always Trust" policy is completely ignored. The certificate remains untrusted until the user manually opens System Settings and explicitly changes the trust settings.

Our DLP agent is specifically designed for environment where MDM is not present and we can not rely on MDM to push profiles.

Is it officially possible to set "Always Trust" for certificate programmatically from a LaunchDaemon?

Thank you in advance!

Answered by DTS Engineer in 888498022
Is it officially possible to set "Always Trust" for certificate programmatically from a LaunchDaemon?

No.

Furthermore, it’s not possible to programmatically install a trusted anchor without user interaction. This isn’t a bug, but the result of a security hardened effort a few years back.

Our DLP agent is specifically designed for environment where MDM is not present …

MDM is the standard way around this. If you can’t rely on MDM then you’ll have to ask the user to approve the anchor.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Is it officially possible to set "Always Trust" for certificate programmatically from a LaunchDaemon?

No.

Furthermore, it’s not possible to programmatically install a trusted anchor without user interaction. This isn’t a bug, but the result of a security hardened effort a few years back.

Our DLP agent is specifically designed for environment where MDM is not present …

MDM is the standard way around this. If you can’t rely on MDM then you’ll have to ask the user to approve the anchor.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hello,

Thank you for response.

Is there any way to reset the "Always Trust" policy?

The following sequence of commands leads to installing a root CA with the "Always Trust" policy:

  1. sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /<some path>/MyCertificate.cer
  2. change policy to "Always Trust"
  3. sudo security delete-certificate -c "MyCertificate.cer" /<some path>/MyCertificate.cer
  4. sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /<some path>/MyCertificate.cer

Result: the newly installed certificate is trusted after step 4.

Thank you for the help!

Is there any way to reset the "Always Trust" policy?

These are known as trust settings and they have both a command-line and API presence.

On the command line, use various subcommands of the security tool:

% security | grep trust-settings
    dump-trust-settings                  Display contents of trust settings.
    user-trust-settings-enable           Display or manipulate user-level trust settings.
    trust-settings-export                Export trust settings.
    trust-settings-import                Import trust settings.

Programmatically, you have a bunch of Trust Settings APIs.

IMPORTANT Neither of these let you set up a trusted anchor without user approval. Or at least they shouldn’t (-: If you find a way to do that, lemme know and I’ll file a security bug about it!

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hello, Thank you for the help.

As I understand it, trust settings are stored separately from the certificate. Does this mean that I can pre-configure the necessary settings during the software installation? For example, by having a post-install script call "security trust-settings-import".

The second question is about "security trust-settings-import" usage. From what I see, security trust-settings-import operates on an XML file that contains the entire list of trust settings (previously generated by trust-settings-export). Is there a supported way via the command line to import trust settings for only one specific certificate, rather than applying or merging the entire global list? For example, can the XML file be stripped down to only include the target certificate, or is there another CLI approach to apply custom trust settings to a single certificate during installation?

Thank you in advance.

trust settings are stored separately from the certificate.

Correct. Although that’s an implementation detail, not something I’d considered to be API. Honestly, the fact that trust settings survive you removing and then re-installing an anchor certificate always struck me as a bug (although I never filed a bug report about it, so I don’t know if the Security framework team agree me with me about that).

Does this mean that I can pre-configure the necessary settings during the software installation?

I’ve no idea. And even if it does work, is it something you want to base a product on? It’s skating close to the edge of implementation details, at least IMO.

Is there a supported way via the command line to import trust settings for only one specific certificate … ?

I doubt it, but I’m hardly an expert in our command-line tools. That the purview of (the higher tiers of) Apple Support.

You can do this with the API [1].

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] The Special Considerations section of that doc looks like it’s somewhat out of date.

Hello,

Thank you a lot for the time and responses! However, further research into the certificate installation completely confused me.

  1. sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <path to cert>
  2. security find-certificate -c "my cert name" -Z | grep "SHA-1 hash:" | awk '{print $3}'
  3. security trust-settings-export -d ExportedTrustSettings.plist
  4. Modify the 'ExportedTrustSettings.plist' file. Find and remove the section with the key generated in step 2.
  5. sudo security trust-settings-import -d ExportedTrustSettings.plist
  6. Check if the trust setting is reset.
  7. sudo security delete-certificate -c "my cert name" /Library/Keychains/System.keychain
  8. sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <path to cert>

Result: the certificate is trusted.

I cannot understand whether this is a bug, a feature, or an incorrect use of the 'security' tool.

Thank you in advance!

Programmatically installing a Root CA with "Always Trust" via LaunchDaemon for DLP agent
 
 
Q