I'm developing an authorization plugin for macOS and encountering a problem while trying to store a password in the system keychain (file-based keychain). The error message I'm receiving is:
Failed to add password: Write permissions error.
Operation status: -61
Here’s the code snippet I’m using:
import Foundation
import Security
@objc class KeychainHelper: NSObject {
@objc static func systemKeychain() -> SecKeychain? {
var searchListQ: CFArray? = nil
let err = SecKeychainCopyDomainSearchList(.system, &searchListQ)
guard err == errSecSuccess else {
return nil
}
let searchList = searchListQ! as! [SecKeychain]
return searchList.first
}
@objc static func storePasswordInSpecificKeychain(service: String, account: String, password: String) -> OSStatus {
guard let systemKeychainRef = systemKeychain() else {
print("Error: Could not get a reference to the system keychain.")
return errSecNoSuchKeychain
}
guard let passwordData = password.data(using: .utf8) else {
print("Failed to convert password to data.")
return errSecParam
}
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: service,
kSecAttrAccount as String: account,
kSecValueData as String: passwordData,
kSecUseKeychain as String: systemKeychainRef // Specify the System Keychain
]
let status = SecItemAdd(query as CFDictionary, nil)
if status == errSecSuccess {
print("Password successfully added to the System Keychain.")
} else if status == errSecDuplicateItem {
print("Item already exists. Consider updating it instead.")
} else {
print("Failed to add password: \(SecCopyErrorMessageString(status, nil) ?? "Unknown error" as CFString)")
}
return status
}
}
I am callling storePasswordInSpecificKeychain
through the objective-c code. I also used privileged in the authorizationDb (system.login.console).
Are there specific permissions that need to be granted for an authorization plugin to modify the system keychain?
You can only write to the system keychain when running as root. Authorisation plug-ins don’t necessarily run as root:
-
By default, they run as
_securityagent
. -
To run as root, you need to add the
Privileged
flag to yourMechanisms
array entry.
IMPORTANT Plug-ins running as root can’t display UI. If you want to do that and write to the System keychain, you’ll need two mechanisms, one standard one and one privileged one. Pass data between the two using the authorisation context.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"