User interaction required for SecTrustSettingsSetTrustSettings

According to the documentation on SecTrustSettingsSetTrustSettings

"When making changes to per-user trust settings, the user is prompted with an alert panel asking for authentication (user name and password or other credentials normally used for login). Therefore, it is not possible to modify per-user trust settings when not running in a GUI environment (that is, when the user is not logged in via the login window). When making changes to system-wide trust settings, the user is prompted with an alert panel asking for an administrator’s name and password unless the calling process is running as root, in which case no further authentication is needed."

And under SecTrustSettings.h it says

* Trust Settings are configurable by the user; they can apply on three levels
 * (called domains):
 *
 * -- Per-user.
 * -- Locally administered, system-wide. Administrator privileges are required
 *    to make changes to this domain.
 * -- System. These Trust Settings are immutable and comprise the set of trusted
 *    root certificates supplied in Mac OS X. 

As we can see, kSecTrustSettingsDomainAdmin is the "system-wide" options that we should be using in SecTrustSettingsSetTrustSettings but when I run the following code, I get a GUI prompt regardless.

    SecKeychainRef keychain;
    SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &keychain);
    SecCertificateRef test = SecCertificateCreateWithData(NULL, certData);
    SecCertificateAddToKeychain(test, keychain);
    SecTrustSettingsSetTrustSettings(test, kSecTrustSettingsDomainAdmin, NULL);

I am running the project as root via the xcode scheme.

Post not yet marked as solved Up vote post of Vzor Down vote post of Vzor
1.3k views

Replies

Modern systems require user interaction to manipulate any trust settings. You wrote:

I am running the project as root via the xcode scheme.

It sounds like you’re under the misapprehension that “running … as root” is the same as “Administrator privileges”. That’s not the case. Changing trust settings requires user interaction regardless of the BSD level privileges of your process.

Why are you changing trust settings? In general this is not a happy path to be going down.

Share and Enjoy

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

  • I am running as root because I am trying to reproduce the behavior described in the documentation for SecTrustSettingsSetTrustSettings "the user is prompted with an alert panel asking for an administrator’s name and password unless the calling process is running as root". I am trying to trust a ssl cert for a github action, and it is headless.

  • Sorry if this a duplicate, my original comment disappeared. This is for a github action so it is headless. I need to add a ssl cert to test our product. I am running as root because as the documentation for SecTrustSettingsSetTrustSettings says "the user is prompted with an alert panel asking for an administrator’s name and password unless the calling process is running as root".

Add a Comment

Why are you changing trust settings?

Adding an SSL certificate to the machine for secure communication.

Running a process as "root" requires authentication by the OS, making it redundant. But to the OP's point, this prompt seems to mismatch the documentation, which clearly indicates that no further action is required, quoting it again:

"[...] When making changes to system-wide trust settings, the user is prompted with an alert panel asking for an administrator’s name and password unless the calling process is running as root, in which case no further authentication is needed. [...]

The documentation warns that this can and will block, quoting:

"[...] Note that this function might block while waiting for user input. [...]

... so I find the OP's question to be valid.

It sounds like you’re under the misapprehension that “running … as root” is the same as “Administrator privileges”.

I'm having a hard time understanding where this assumption was drawn from, the OP clearly says "root". XCode calls this root:

  • Product > Scheme > Edit Scheme > Debug process as root

Changing trust settings requires user interaction regardless of the BSD level privileges of your process.

I'm having a hard time understanding if this is suggesting that the documentation is outdated, or if the Scheme is not doing as described?

In general this is not a happy path to be going down.

Reading between the lines, I think there's some assumption that modifying the SSL trust settings is bad practice. This is both presumptuous as well as untrusting. In my use-case, myself and my company have been vetted by Apple through Dun & Bradstreet. Each application distributed undergoes notarization and stapling by Apple, however there are use-cases where this User Interaction blocks similarly as documented (but even when running as root). I think the OP's question as well as the quoted documentation have merit and as a result promote happiness. :)

More strictly speaking, self-signed certificates are arguably more secure than CA-issued certificates because the chain of trust does not imply monolith issuers. Furthemore, when done properly, private key leakage will only impact a single machine.

I understand there are some cases where self-signed certificates are lazily installed (e.g. SuperFish / Lenovo) and those concerns have merit as well, but then this turns more into a conversation about the dangers in self-signed certificate (e.g. wildcard and/or non-owned FQDN and/or non-localhost) scope, rather than about security in general. Furthemore, in the event of the SuperFish / Lenovo disaster, it was the worldwide private-key sharing across all devices that made the scope so terrifying. Perhaps this behavior should be fingerprinted and added as a blocker to the notarization process, since I've seen other apps (e.g. Cricut) continue this practice years after that fiasco. :(

Oddly, Apple does have a plist flag for suppressing this prompt, but this technique seems like using a sledgehammer to crack a nut, and due to how contradictory this appears from a security perspective, can be presumed will be removed in a future OS update.

There are two cases here:

  • Installing a trusted anchor via APIs.

  • Installing a trusted anchor via MDM.

Most organisations that use a custom CA install its root certificate via MDM. Indeed, that’s the only option on iOS and its child platforms [1]. If you want to use a custom CA, that’s the path you should be on.

this prompt seems to mismatch the documentation, which clearly indicates that no further action is required

Indeed. Our policies have changed as part of ongoing security hardened efforts. Feel free to file a bug against the docs.

I think there's some assumption that modifying the SSL trust settings is bad practice.

Correct.

Well “bad practice” is probably a little extreme, but it’s certainly not the happy path. The fact that these APIs exist at all is due to macOS’s age. These APIs are not available on iOS and that’s not an accident:

  • In managed environments, you should install your custom CA’s root certificate via MDM.

  • In unmanaged environments, we strongly recommend that you configure your servers with a digital identity whose certificate was issued by a CA that’s trusted by default. If you ignore that advice then you should override TLS server trust evaluation inside your app rather than system wide.

self-signed certificates are arguably more secure than CA-issued certificates because the chain of trust does not imply monolith issuers.

Using a CA-issued certificate is just the first step. If you want to apply additional security on top of that, feel free to do so. App Transport Security, used by our high-level HTTP APIs, supports this directly via the NSPinnedDomains property.

Share and Enjoy

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

[1] Technically this is using MDM to install a configuration profile, and you can install a configuration profile manually, but:

  • Manually isn’t an API.

  • The user still has to take extra steps to enable the anchor.

Most organisations that use a custom CA install its root certificate via MDM. Indeed, that’s the only option on iOS and its child platforms [1]. If you want to use a custom CA, that’s the path you should be on.

iOS does offer installing custom device profiles for this exact purpose (which MDMs can automate). It's an unfortunate side-effect of the mobile landscape. I do admit that these profiles (whether provided via MDM or manually) do place iOS better than Android in this area, but this conversation is about the MacOS desktop. Mobile platforms are not the target for this app due specifically to their strict sandboxing.

In regards to MDM solutions, these just don't scale well for non-enterprise deployments. The simple act of proposing an MDM solution for an SSL problem is quite presumptuous. In my case, SSL is needed for websocket communication from browser to a natively running application. This application is distributed to millions of PCs worldwide and macOS is the only platform that places a blocking UI prompt in this fashion.

To that point, macOS is also the only one to warn of other important security, privacy and non-sandboxed actions, which is fantastic, but these are all non-blocking. For example, the same application must make changes in other areas of the OS (background tasks, browser helpers) and the OS -- quite politely -- asks if this is OK, something no other OSs keep track of, which is a step in the right direction. To that point, SSL is so important and prolific in the industry it should come as no surprise that there are perfectly valid use-cases for limited scope certificates, perhaps this is the biggest oversight of prescriptive solutions, that once you mandate SSL everywhere, private-network communication is left in the dust unless exceptions to the assumption of "HTTPS = public websites" are made.

Using a CA-issued certificate is just the first step.

I'll have to strongly disagree. Using CA-issued certificates inside distributed applications is a substantial security risk. Furthemore, CA-issued certificates can't easily be issued for localhost or LAN communication anyway. If you're aware of a non-enterprise way to do this, I'm all ears. :)

In an attempt to stay on topic, I'll file a bug against the documentation. Disclaimer, the OP -- Vzor -- and I have been discussing this problem offline. He'll be sharing a GitHub actions CI issue that suffers a similar problem.

Feel free to file a bug against the docs.

Done via FB11983426 (<-- hmm... this auto-linking is broken, shall I file another?). As a slight aside, I reported an unrelated bug with Notes (FB11709965) on Ventura beta that still seems to be present, so my confidence in this system has yet to be won over. :)