I am storing a generic password using the macOS Keychain Services. This password should be usable without prompting by an Apple app already on the system. I initially create it using code something like this:
itemName="Some Item"
appPath="/Applications/Some Apple.app"
security add-generic-password -a "$username" -s "$itemName" -w "$password" -T "$appPath" "$keychain"
security set-generic-password-partition-list -a "$username" -s "$itemName" -S apple: -k "$password" "$keychain"
That works fine and the app is able to use it without the user being prompted for permission.
However, if I later go to update this password, the user gets a one-time prompt when the other app needs the password — even though the ACLs for the item haven't changed!
For example after running the code
private func updateAppPassword(user: String = NSUserName(), password: String) throws {
let query: [CFString:Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrServer: "Some Item",
kSecAttrAccount: user
]
let newInfo: [CFString:Any] = [
kSecValueData: password.data(using: .utf8)!
]
try SecItemUpdate(query as CFDictionary, newInfo as CFDictionary).check()
}
…when the user launches the Apple app that uses the password, they have to give permission.
This isn't 100% surprising since I did change the item, but I don't know why updating it should matter especially since I've left the permissions just as they were created — and after the initial creation of the keychain item there is no prompt!
Especially odd, both before and after I run the code to updated the password, I get the following from security dump-keychain -a
on my test keychain:
keychain: "/Users/me/Library/Keychains/dev-test.keychain-db"
version: 512
class: "genp"
attributes:
0x00000007 <blob>="Some Item"
0x00000008 <blob>=<NULL>
"acct"<blob>="vand065"
"cdat"<timedate>=0x32303138303730353139303835385A00 "20180705190858Z\000"
"crtr"<uint32>=<NULL>
"cusi"<sint32>=<NULL>
"desc"<blob>=<NULL>
"gena"<blob>=<NULL>
"icmt"<blob>=<NULL>
"invi"<sint32>=<NULL>
"mdat"<timedate>=0x32303138303730353139313035305A00 "20180705191050Z\000"
"nega"<sint32>=<NULL>
"prot"<blob>=<NULL>
"scrp"<sint32>=<NULL>
"svce"<blob>="Some Item"
"type"<uint32>=<NULL>
access: 5 entries
entry 0:
authorizations (6): decrypt derive export_clear export_wrapped mac sign
don't-require-password
description: Some Item
applications (1):
0: /Applications/Some Apple.app (status -2147415734)
entry 1:
authorizations (1): encrypt
don't-require-password
description: Some Item
applications: <null>
entry 2:
authorizations (1): integrity
don't-require-password
description: 53f29c48f37f1d8993800d34b13495e926a1e8f64121c2f7e7a6d23128d1bb73
applications: <null>
entry 3:
authorizations (1): partition_id
don't-require-password
description: apple:
applications: <null>
entry 4:
authorizations (1): change_acl
don't-require-password
description: Some Item
applications (0):
I.e. there appears to be no change made to the keychain item or its ACL by the password update. So why does the user have to give "/Applications/Some Apple.app" permission again to use the updated password?
User contributions licensed under CC BY-SA 3.0