Sandboxed app and command line tool but Apple Events require temporary-exception

My sandboxed app contains a command line tool (CLT) also sandboxed.

The command line tool sends an Apple Event to the app but this works only if the CLT entitlements contains

Code Block
<key>com.apple.security.temporary-exception.apple-events</key>
<array>
<string>com.my-app-bundle-id</string>
</array>


The CLT and bundle ids are identical, the team id is identical, too

I can't find where the error is hidden, may you help me?

The app is distributed via the Mac App Store

I show below the plist and entitlements

App entitlement


Code Block
<?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>
<array>
<string>$(TeamIdentifierPrefix)com.appgroup.myapp</string>
</array>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>


App plist


Code Block
<?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>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>myapp</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>myext</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>my</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/octet-stream</string>
</array>
<key>CFBundleTypeName</key>
<string>myapp</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>NSDocumentClass</key>
<string>VDDocument</string>
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleHelpBookFolder</key>
<string>myappHelp</string>
<key>CFBundleHelpBookName</key>
<string>com.myapp.help</string>
<key>CFBundleIconFile</key>
<string>my.icns</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>
<string>2010, myapp.com</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
</dict>
</plist>


Command line tool plist


Code Block
<?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>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.myapp.myclt</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>codesign</string>
<key>CFBundleVersion</key>
<string>1.2</string>
<key>NSAppleEventsUsageDescription</key>
<string>Please give my command line tool access to my app</string>
</dict>
</plist>


Command line tool entitlement


Code Block
<?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>
<array>
<string>$(TeamIdentifierPrefix)com.appgroup.myapp</string>
</array>
<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.temporary-exception.apple-events</key>
<array>
<string>com.myapp</string>
</array>
</dict>
</plist>


The command line tool sends an Apple Event to the app but this works
only if the CLT entitlements contains
com.apple.security.temporary-exception.apple-events.

Right. A sandboxed app (well, in this case, a sandboxed tool) needs this entitlement in order to send arbitrary Apple events.

There is an alternative here, namely com.apple.security.scripting-targets. See Enabling Scripting of Other Apps in the Entitlement Key Reference.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Right. A sandboxed app (well, in this case, a sandboxed tool) needs this entitlement in order to send arbitrary Apple events.

The Apple events destination is only the app contained in the same tool bundle, the temporary entitlement sounds a bit extreme in this case


There is an alternative here, namely com.apple.security.scripting-targets. See Enabling Scripting of Other Apps in the Entitlement Key Reference.

I already found this info but this sounds like another level of complexity with its scriptable app’s scripting access groups.

If your app needs to control another scriptable app, your app can use
the scripting targets entitlement to request access to one or more of
the scriptable app’s scripting access groups.


Thanks again to point me out to the right direction

the temporary entitlement sounds a bit extreme in this case

Indeed. I think you could reasonably argue that the Apple event security model should be less strict when it comes to apps created by the same team. However, that’s not how it currently works.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
@Quinn - Sorry to dredge up an older thread. I've gone through many of your replies on this topic (which were much appreciated, btw) and I'm confused.

The link you mentioned also states:

"Before you can use this entitlement, the scriptable app must provide scripting access groups. If it does not, you can still control the app, but you use a temporary exception entitlement instead. In some cases, you may use both scripting-targets entitlement and a temporary entitlement together, to provide support across different versions of the OS. For more information, see Apple Event Temporary Exception."

As I learn more about this I'm trying to reconcile:
  • In the case of the scripting-targets entitlement, it reads like the target app must support scripting security groups

  • If the target app does not use scripting security groups you need to use a temporary exception

  • From what I've read on the discussion forums it sounds like using temporary exceptions = app store rejection

Or that's how I've read things. Assuming my understanding is correct, is there a suggested process for communicating with external apps using AppleScript when they don't have security groups?

We have an academic research app that can only use AppleScript to communicate with external 3rd party statistical tools and Microsoft Office. The other apps don't offer any other mechanism, but AppleScript. Not all of them (any of them?) offer security groups for the current version(s) of their apps and we need to be able to support historical versions up to 5 years prior. We currently distribute our app outside of the app store, but had discussed trying to fully sandbox it so it could be distributed via the app store as a convenience to users.

From what I'm reading into this I think avoiding the app store and just continuing to offer a download on our university web site may be the best/most practical option, but I'll admit I might simply not be fully understanding the app store rules.

Any insight much appreciated
Thank you

From what I'm reading into this I think avoiding the app store and just continuing to offer a download on our university web site may be the best/most practical option, but I'll admit I might simply not be fully understanding the app store rules.

I think that would be the best course of action. Don't forget that the Mac App Store is going to add another layer of licensing onto the app. Free or not, it will be linked to the original downloader's Apple ID and subject to various other Apple licensing issues. Apple has some other programs for enterprise and business customers. I know nothing about them and I don't know if they would help.

Also, you have to remember that 3rd party developers think in terms of sandbox == Mac App Store. From Apple's perspective, the app sandbox and the Mac App Store are two completely different things. The Mac App Store does require sandboxing, along with a long list of other requirements. Apple's intention is that ALL apps should be sandboxed, whether or not they are in the Mac App Store.

Therefore, along with a number of technical issues getting AppleScript to work from the sandbox, there is another set of procedural requirements for the Mac App Store that go above and beyond those technical requirements. And don't think you can use other apps as a reference for what is technically and procedurally possible. Just because a handful of very popular apps can do exceptional things in the Mac App Store doesn't mean that Apple will extend those privileges to your app.

Sandboxed app and command line tool but Apple Events require temporary-exception
 
 
Q