Sandboxed NE System Extension cannot access Keychain

I am building a Transparent Proxy Network Extension for Developer ID publication (i.e. not Mac App Store). When testing, I ran the NE as an Application Extension (appex -- entitlement app-proxy-provider), and that ran as the active user in an App Sandbox. Part of my extension reads the system root certificate store (both admin and system domains) from Keychain using the Security framework, and this all worked perfectly fine.

However, since my app is non-MAS, the extension must be made into a System Extension (entitlement app-proxy-provider-systemextension). This means my extension is now running as root and unsandboxed, which is definitely not ideal. So I re-enabled App Sandbox on the extension, and surprisingly it actually works. (I've been unable to get an executable running as root to use an App Sandbox in the past, e.g. through sandbox-exec or otherwise.)

The problem is that the root sandbox seems more restrictive than the regular user sandbox. Namely, unlike the appex's sandbox, it cannot seem to access Keychain at all. Trying to read the admin and system certificate store fails. For example, using the function SecTrustSettingsCopyCertificates on the system domain returns the error No Trust Settings were found. Additionally, these logs are written to the system Console when I called the function.

Code Block
error kernel Sandbox: [my bundle id](1478) deny(1) file-write-data /private/var/db/mds/system/mds.lock
default [my bundle id] MacOS error: -25337
default [my bundle id] CSSM Exception: 3 unknown error 3=3
default [my bundle id] CSSM Exception: -2147414013 CSSMERR_DL_MDS_ERROR
default [my bundle id] CSSM Exception: -2147414013 CSSMERR_DL_MDS_ERROR

So it looks like the Sysex running in an App Sandbox as root prevents access to MDS (CSSM Module Directory Service, perhaps? Or is it Spotlight's Metadata Service?), which I guess breaks the Keychain lookups. Other functions to access the Keychain, such as SecItemCopyMatching, also fail with the same sandbox errors logged to console.

Surprisingly, a solution that seems to solve the problem is to use a temporary-exception to allow mds.lock.

Code Block
<key>com.apple.security.temporary-exception.files.absolute-path.read-write</key>
<array>
<string>/private/var/db/mds/system/mds.lock</string>
</array>

However, this obviously seems quite sketchy, especially since I'm not even sure what mds is.

So, ultimately, my question is: is there any non-sketchy way to create a Network Extension for non-Mac App Store publication which can run in a secure context (e.g. not root, or root with App Sandbox) and still have access Keychain? Is my temporary-exception solution actually okay for production use?

My extension does not need root permissions, and I took great care to ensure that my userspace proxy daemon was running as unprivileged as possible back with Network Kernel Extensions. It seems silly that now the "more secure" NKE replacement involves requiring NEs to run as root.

Replies

Update: It appears that this Keychain bug no longer exists on Big Sur Beta 5. The original post was reported from Catalina 10.15.6. It would still be helpful to know if there is a solution for Catalina. Thanks!