I am developing a MacOS Authorisation Plugin, I have username and password entry items and utilising SFAuthorizationPluginView to display that. I am able to do so.
Requirement is I have to store ed25519 private key in PEM format in System Keychain as I need to read this entry before login to sign a request to a remote server.
I only want my authorisation plugin to access this private key in System Keychain.
I am looking up resources on the internet but I could not find specific to macOS Authorisation plugin, many are specific to iOS and some point at using entitlements and app group, but I doubt that applies to macOS authorisation plugin.
I'll really appreciate if some pointers are shared how can I store a private credential in System Keychain so that it can be used by only my plugin only, and this is before I have logged into the system.
This is tricky.
To start, make sure you read TN3137 On Mac keychain APIs and implementations. Nothing I say here will make any sense without that background.
An authorisation plug-in is loaded by a host process. You have no control over the entitlements of that process. That means you can’t use the data protection keychain in your plug-in. You have to use the file-based keychain.
Your plug-in can be hosted by two different process, depending on whether the system is running a privileged mechanism or not. For the current host names, see this post. In the privileged case, the host is running as root. In the non-privileged case, it’s running as _securityagent
. That affects what keychain you can use:
-
In the privileged case, you only have access to the System keychain.
-
In the non-privileged case you could use the login keychain for
_securityagent
. You can also read from the System keychain.
My advice is that you not do the latter. If you need this item in a non-privileged mechanism, have a privileged mechanism that gets this keychain item and put its into the authorisation context.
Alternatively, you could create a launchd
daemon and have it manage the credential on your behalf. Honestly, this isn’t a bad option, because it means you can do work in a known environment, rather than the limited environment in which your authorisation plug-in is loaded.
IMPORTANT This won’t let you use the data protection keychain though. TN3137 makes it clear that a daemon can only use the file-base keychain.
Requirement is I have to store ed25519 private key in PEM format
The keychain does not support PEM format directly. And it doesn’t really support Curve 25519. If you really want PEM, store that in a generic password keychain item (kSecClassGenericPassword
). If you’re prepared to convert it to DER, you could use a key item (kSecClassKey
) but setting the key type will be tricky. Honestly, if you’re required to use Curve 25519, I’d use a generic password in either case.
so that it can be used by only my plugin only
That’s not really possible. Remember that macOS enforces privileges at the process boundary, and all authorisation plug-ins are loaded by the same host process. Even if you manage the item with a launchd
daemon, you can’t tell whether the XPC connection to operate on that item is coming from your plug-in loaded in the host process or some other plug-in loaded in the host process.
Note XPC is Apple’s preferred IPC mechanism. See XPC Resources for links to documentation and more.
Finally, before you try to use the SecItem API, read these:
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"