Quinn, Thanks for the response and I could follow it well. Taking your advice I am using following option.
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.
However, I am finding it difficult to quickly prototype (command line) logic to add entry into System Keychain.
I found some examples but it seems to be using deprecated API.
Only thing that seems to be working is using security command line tool as. I plan to run the below command as simple Process#launch. I tried it in authorisation plugin to run something else which gave result, hoping will work fine for below command.
sudo security add-generic-password -a root -s "MySecureEntry" -w "my-secret-value" -T "" /Library/Keychains/System.keychain
Note, -T ""
Without giving it, the below program can read the value without sudo.
I can read that entry in root context as follows (command line app run with sudo).
func getKeychainEntry(service: String, account: String) -> String? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecReturnData as String: true
]
var dataRef: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &dataRef)
if status == errSecSuccess, let data = dataRef as? Data {
return String(data: data, encoding: .utf8)
} else {
print("Failed to retrieve from Keychain: \(status)")
return nil
}
}
I am not feeling good about what I am doing above, is there a better way? Apologies if question feels silly.