Using AppleScriptObjC, is there a reliable method to test if an Xcode app is granted to access full disk?
I thought there might be a way to use TCC.framework , so I spent some time trying a few different approaches, but I couldn’t get it working.
As far as I could find, the only options seem to be either using SQLite3 directly from Swift or, as you probably already know, calling /usr/bin/sqlite3 via NSTask .
Accessing "/Library/Application Support/com.apple.TCC/TCC.db" requires Full Disk Access.
Just for reference:
CheckTCC.zip (2.4 KB)
Working with the TCC Framework should be possible if - because it’s one of Apple’s Private Frameworks - directly called by runtime via NSBundle inside of an Applet. There are also entitlements which have to be set for the Process the Applet is starting, because of tccd which will block the whole thing otherwise.
Which entitlements there have to be set I currently don’t have in my documentation, neither any code examples, I’m sorry.
I hope at least the theory is a helpful tip for you.
Maybe there is even a way using tccutil with NSTask … I don’t really know… just a hint since it’s something you both didn’t mention jet in this thread.
I hope that even my incomplete knowledge is anything like a helping thing.
Greetings from Germany ![]()
Tobias
@IceFole I’m not sure I follow. What does the attached file do?
@Nr.5-need_input Thanks for the insights.
In fact, until now, I’d been using the good old method @Shane_Stanley suggested: testing if a system file could be read. But for a few days, I was surprised to find it wasn’t working anymore. Why? Who knows…
For those whose interested, here a working code:
use framework "Foundation"
use framework "AppKit"
use scripting additions
-- check that full disk access is granted
set theTest to current application's NSURL's fileURLWithPath:"/Library/Preferences/com.apple.TimeMachine.plist"
set {theTest, theError} to current application's NSData's dataWithContentsOfURL:theTest options:0 |error|:(reference)
if theTest = missing value then
tell application id "com.apple.systempreferences"
activate
reveal anchor "Privacy_AllFiles" of pane id "com.apple.settings.PrivacySecurity.extension"
end tell
end if
Sorry about that. My explanation wasn’t very clear.
I’m not very good at English, so I hope you’ll forgive my poor explanation.
In AppleScript, it would look something like this.
If you run it from Script Editor, Script Editor itself needs Full Disk Access.
#!/usr/bin/env osascript
#coding: utf-8
use AppleScript version "2.8"
use scripting additions
set strFilePath to ("/Library/Application Support/com.apple.TCC/TCC.db") as text
set strBundleID to ("com.apple.dt.Xcode") as text
set strCmd to ("/usr/bin/sqlite3 -cmd \".timeout 5000\" -cmd \"PRAGMA query_only = ON;\" \"" & strFilePath & "\" \"SELECT auth_value FROM access WHERE service = 'kTCCServiceSystemPolicyAllFiles' AND client = '" & strBundleID & "';\" 2>/dev/null") as text
log strCmd
set strStdOut to (do shell script strCmd) as text
if strStdOut is "0" then
return false
else if strStdOut is "2" then
return true
end if
macOS stores privacy permissions, including Full Disk Access, in the TCC database (TCC.db).
This script checks whether Xcode has been granted Full Disk Access .
It does this by reading the TCC database (TCC.db ) and looking up the kTCCServiceSystemPolicyAllFiles permission for the bundle identifier com.apple.dt.Xcode .
It returns:
-
trueif Full Disk Access is granted. -
falseif it is not.
If you run this script from Script Editor , Script Editor itself must also have Full Disk Access, because it needs permission to read the TCC database.
This is what works on my system. 26.6(25G72)
Perfect! It’s working great.
set myDB to "/Library/Application Support/com.apple.TCC/TCC.db"
set myID to "com.apple.dt.Xcode"
try
set myShell to "/usr/bin/sqlite3 -cmd \".timeout 5000\" -cmd \"PRAGMA query_only = ON;\" " & quoted form of myDB & " \"SELECT EXISTS(SELECT 1 FROM access WHERE service = 'kTCCServiceSystemPolicyAllFiles' AND client = '" & myID & "' AND auth_value = 2);\""
return (do shell script myShell) as integer
on error
return -1
end try