System Application Data

Hi all,

First I'd like to say that i like the changes that Apple has introduced into macOS 10.14 regarding privacy! But the documentaiton about the details is a bit sparse.


In this session: https://developer.apple.com/videos/play/wwdc2018/702/

Minute 12:10 the presenter mentions that the user can preauthorize Applications to access System Application Data.


I have multiple questions about this Privacy Setting:

  • Is there an API to check wether the user has preauthorized my Application to access System Application Data?
  • Is there an API call which returns a list of protected paths? Or a configuration file that I can parse, which contains the protected paths.
  • Will an App that is targeting the macOS Mojave SDK be killed if it tries to access System Application Data without preauthorization?
  • Is a process authorized when it is started by an authorized Application?
  • Is only the main executable file authorized or all executables within the Application bundle?
  • Is there any written documentation about this topic?


Best Regards

Timo

Hi all,


Our team will also be potentially affected by these changes.

It would be extremely helpful if any kind of documentation on this topic is published.


Best regards,

Robert

I could find no documentation other than the slides of that WWDC session.


There seems to be no API to check on authorization status - short of trying to read known protected paths.

There seems to be no API to request authorization from the user. Instead one needs to direct the user to a panel buried deep in System Preferences.

There is no standard UI that one could invoke to walk the user through the process.


I have filed bug reports for the above. Please do the same. The more "upvotes" the better.


Also check out: https://www.felix-schwarz.org/blog/2018/06/apple-event-sandboxing-in-macos-mojave

Apple Events/Script is affected by similar problems.


The state of affairs on Application Data is even worse than for Apple Events:


There is no error code returned when trying to access protected data. Directories simply appear to be empty - which they very well may be.


The System Preferences pane for Application Data preferences expects the user to manually add the application to preauthorize. It does not automatically list all applications or applications that have recently attempted to gain access. The user needs to know where the application is installed and navigate there using a NSOpenPanel that starts in the most unlikely places of all: ~/Documents.

I have filed two bug reports about the missing Documentation and APIs.


It is really frustrating to receive no official answer from Apple, you can not open a Code-Level Support ticket because it is beta Software and you don't get an answer here in the forum nor from the bug report either.


Our current backup assumption how to at least somewhat deterministic query the privacy setting would look something like this: (NOT TESTED DO NOT USE...)

import Darwin
import SQLite3

// Note: the TTCD does not like if another process reads from the DB directly. I noticed weird glitches when I ran this code.
// The list view in 'System Preferences > Security & Privacy > Privacy > Application Data' was shown empty 
// although the table itself contained other entries.

func applicationDataAccess() -> Bool? {
    let tccDBPath = "/Library/Application Support/com.apple.TCC/TCC.db"
    let os = ProcessInfo().operatingSystemVersion
    if os.majorVersion == 10 && os.minorVersion < 14 {
        // There is no Privacy protection before Mojave
        return true
    }

    // check if the TCC.db can be accessed or if it might be protected by the privacy protection
    let fd = open(tccDBPath, O_RDONLY)
    if fd < 0 {
        if errno != EPERM {
            // if an open is blocked by the new privacy protection errno is set to EPERM
            // if errno is different we can not reliably say what's what
            return nil
        }
        return false
    }
    close(fd)

    var tccDB: OpaquePointer? = nil

    guard sqlite3_open_v2(tccDBPath, &tccDB, SQLITE_OPEN_READONLY, nil) == SQLITE_OK else {
        // the db can't be opened so what does that mean? --> nil
        return nil
    }

    defer {
        sqlite3_close(tccDB)
    }

    // if bundle doesn't contain an id fall back to path
    let clientName = Bundle.main.bundleIdentifier ?? Bundle.main.bundlePath
    let query = """
SELECT allowed
FROM access
WHERE service = "kTCCServiceSystemPolicyAllFiles"
    AND client = "\(clientName)";
"""

    var queryStatement: OpaquePointer? = nil
    guard sqlite3_prepare_v2(tccDB, query, -1, &queryStatement, nil) == SQLITE_OK else {
        return nil
    }
    if sqlite3_step(queryStatement) == SQLITE_ROW {
        return sqlite3_column_int(queryStatement, 0) == 1
    } else {
        return false
    }
}


Let's hope that we will receive propper API so that we don't have hacks like this! Plus this code won't work in a sandboxed application!

System Application Data
 
 
Q