electronelectron-buildermac-app-storeappstore-sandboxentitlements

Proper entitlements to automatically open directory on macOS


I build an app with electron that saves text to files in a user selected directory. On app startup the user selects the directory where his data should be stored. I save that directory with electron-settings and with the next app startup the directory is automatically loaded again.

Locally everything works great, but I have trouble getting it to work packaged for an macOS .app file and after signing.

My entitlements currently look like this

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.application-groups</key>
    <string>APPLE_GROUP_STRING</string>
    <key>com.apple.security.files.user-selected.read-write</key>
    <true/>
    <key>com.apple.security.files.bookmarks.document-scope</key>
    <true/>
    <key>com.apple.security.files.bookmarks.app-scope</key>
    <true/>
  </dict>
</plist>

When I select a directory everything works great, but when I close the app and then try to read/write files to the same directory I get a 'permission denied' error. (After manually selecting the directory again it works as expected)

What entitlement do I need to set to allow accessing the directory on startup?
Is there another workaround? Maybe have one button that directly opens the directory without the usual file-selection dialog?

I already tried to use

<key>com.apple.security.temporary-exception.files.absolute-path.read-write</key>
<array>
    <string>/</string>
</array>

but for very obvious reason apple verification rejected the app with read/write access to / 😉


Solution

  • thanks @mahal tertin for pointing to the right direction with security scoped bookmarks.

    since electron 6.0.0 the dialog.showOpenDialog() method returns a promise that resolves to the filePaths and security scoped bookmarks.

    with the app.startAccessingSecurityScopedResource(bookmark) you can now use that bookmark to access the previous resource.

    I wrote a detailed blog post with code examples for more information: https://developapa.com/security-scoped-bookmark/