We have a Mac App Store app that needs access to the Accessibility API. Since 10.9 Mavericks, there is a system whitelist for the apps that want to use the Accessibility API (System Preferences → Security & Privacy → Accessibility).
While testing an update for our app, we have noticed that right after the upgrade from the old version, system tells us that we don’t have a right to use the Accessibility API (AXIsProcessTrustedWithOptions
returns NO
), even though our app is on the whitelist, with the checkbox checked. Once we uncheck and recheck the permission, everything works fine.
Obviously, this is not a acceptable upgrade scenario for us, especially since the accessibility whitelist is buried so deep in System Preferences and can’t be accessed from code.
Is this a system bug? Is there a known workaround? We would accept having to recheck the Accessibility permissions after a big update – it just sucks navigating your users to the System Preferences only to see the checkbox already checked, without the feature working.
Updates:
During the first post-upgrade launch, the system complains in the console:
16/03/15 06:47:10,343 tccd[190]: Unable to verify code signing identity of com.company.app: code failed to satisfy specified code requirement(s)
16/03/15 06:47:10,350 universalAccessAuthWarn[401]: AccessibilityAPI: pid 471, is not allowed to access the accessibility API. Path: /path/to/app
Weird thing is, once the permission checkbox on the accessibility whitelist is unchecked and rechecked, there are no errors in the console during the subsequent launches, even though the binary is the same.
I’ve peeked under the hood into the SQLite database implementing the access whitelist (/Library/Application Support/com.apple.TCC/TCC.db
). The access
table holds a csreq
column that looks like some application fingerprint/hash blob:
$ sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db 'select client, quote(csreq) from access'
com.apple.dt.Xcode|X'…'
com.apple.AccessibilityInspector|X'…'
com.ourcompany.app|X'…'
(The quoted hashes were replaced with “…”.)
Now, if I install the older version of our app and run it, a hash is computed by the system and stored in the csreq
column. If I perform a clean install of the new app version, I get a different hash.
When I install the old version and then delete it, the column still contains the hash for the old version. Could this be the source of the problem? Because when I set the column to NULL
before updating the app, everything works fine. A new hash gets computed, the Accessibility API check returns YES
as it should.
Same issue in a different app on GitHub.
There’s a thing called designated requirement (see the Code Signing Guide). Roughly speaking, it’s a set of criteria that system uses to determine if two app bundles represent the same app, security-wise. The designated requirement can be displayed using the codesign -dvv --req - YourApp.app
command. In our case, the designated requirement check failed, since the older app version was signed using a different certificate than the development build.
In other words, when trying to replace a Mac App Store build with a development build, a security check will fail because of certificate mismatch and you will have to re-check some app permissions. As far as I know, this won’t happen when you have distributed and installed the same build through Mac App Store.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With