Close other apps in sandbox mode

In our application we start and close external applications.

Applications are started by opening the document/Uri of corresponding application.

these application are later closed by using apple script

osascript -e 'tell application \"APP_NAME\" to quit'


This works in normal mode, but not in sandbox mode.


I tried with following entitlements


<key>com.apple.security.temporary-exception.apple-events</key>

<array>

<string>com.microsoft.SkypeForBusiness</string>

<string>com.logmein.GoToMeeting</string>

</array>

<key>com.apple.security.automation.apple-events</key>

<true/>

<key>com.apple.security.scripting-targets</key>

<dict>

<key>com.microsoft.SkypeForBusiness</key>

<array>

<string>com.apple.systemevents</string>

</array>

<key>com.logmein.GoToMeeting</key>

<array>

<string>com.apple.systemevents</string>

</array>

</dict>


and in info.plist

<key>NSAppleEventsUsageDescription</key>

<string>Close apps started by this application</string>


But I get error privilege violation occurred.

GoToMeeting is downloaded from thier website in dmg format and Skype for buisness is pkg.


Is there any issue with entitlements used or any other way to close open apps?

Mac OS used: 10.13.6

Development platform: electron

Accepted Reply

the app is developed using electron, to close the apps gracefully we use applescript.

If your only goal is to terminate an app, using AppleScript makes things way more complex than necessary. Specifically, AppleScript has a habit of sending all sorts of weird and wonderful events to the target process, whereas in this case you really want to focus on the

'quit'
Apple event. And the easiest way to send that is with
NSRunningApplication
.

But first I want know if the entitlement values are correct.

As to how to get that to work, here’s a simple example:

let textEdit = NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.TextEdit").first!
let success = textEdit.terminate()
print("success: \(success)")

This is using these entitlements:

$ codesign -d --entitlements :- …
…
<dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.get-task-allow</key>
    <true/>
    <key>com.apple.security.temporary-exception.apple-events</key>
    <array>
        <string>com.apple.TextEdit</string>
    </array>
</dict>
</plist>

This code works a treat on macOS 10.14.6.

WARNING While I don’t work for App Review, and thus can’t make definitive statements on their behalf, my understanding is that they won’t allow you to use the

com.apple.security.temporary-exception.apple-events
entitlement.

or is there any other way to achieve this in sandbox environment

Not that I’m aware of.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Are you sandboxed for the benefit of Mac App Store distribution? Or are you shipping independently, via Developer ID, and have opted into the sandbox because it’s a good thing?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Yes, sandboxing for Mac App store distribution.

First up, running scripts to quit an app is overkill. A much more lightweight approach is to call

-[NSRunningApplication terminate]
.

However, neither approach will work in a sandboxed app, because the sandbox significantly restricts an app’s ability to interfere with other apps. You could potentially get around this with entitlements (like the

com.apple.security.temporary-exception.apple-events
entitlement you referenced), but such entitlements are carefully reviewed, and most often rejected, by App Review.

Can you walk me through the user scenario here? Why do you need to quit running apps?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the replay.

In the begining of the workflow, we start these apps(conference/screen mirroring) either by "open [URL]" or "open [APP_registered_FILE].

This will make the user to share the screen with others

So at the end of the workflow, these opened app has to be closed.

bz the app is developed using electron, to close the apps gracefully we use applescript.


I understand the using specific entitlements, the possibily of rejection in review is present.

But first I want know if the entitlement values are correct. or is there any other way to achieve this in sandbox environment


Let me know if more info is required.

the app is developed using electron, to close the apps gracefully we use applescript.

If your only goal is to terminate an app, using AppleScript makes things way more complex than necessary. Specifically, AppleScript has a habit of sending all sorts of weird and wonderful events to the target process, whereas in this case you really want to focus on the

'quit'
Apple event. And the easiest way to send that is with
NSRunningApplication
.

But first I want know if the entitlement values are correct.

As to how to get that to work, here’s a simple example:

let textEdit = NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.TextEdit").first!
let success = textEdit.terminate()
print("success: \(success)")

This is using these entitlements:

$ codesign -d --entitlements :- …
…
<dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.get-task-allow</key>
    <true/>
    <key>com.apple.security.temporary-exception.apple-events</key>
    <array>
        <string>com.apple.TextEdit</string>
    </array>
</dict>
</plist>

This code works a treat on macOS 10.14.6.

WARNING While I don’t work for App Review, and thus can’t make definitive statements on their behalf, my understanding is that they won’t allow you to use the

com.apple.security.temporary-exception.apple-events
entitlement.

or is there any other way to achieve this in sandbox environment

Not that I’m aware of.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi.


How about closing *any* app? I need my app uses the System Events to close any app that user adds to a list.

I see in my system preferences a lot of apps having System Events access in Automation panel (e.g. Google's backup and sync or Divvy). How can I ask permissions for that?


Thank you

There’s two levels of security in play here:

  • App Sandbox — This prevents apps from controlling other apps via Apple events except:

    • Where the target app opts into that control (see the documentation for the

      com.apple.security.scripting-targets
      entitlement)
    • When the sending app punches a whole through the sandbox via the

      com.apple.security.temporary-exception.apple-events
      entitlement

    In my experience, App Review takes a dim view of the latter.

  • Apple event authorisation — This is what you’re seeing in the Security & Privacy preferences. This applies to all apps, regardless of whether they are sandboxed or not.

How can I ask permissions for that?

Is your app sandboxed?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for answering. Yes, my app is sandboxed. Sorry for not mentioning it.


I've added the NSAppleEventsUsageDescription to the entitlements but I'm not sure how to set the com.apple.security.temporary-exception.apple-events instead of passing an array of bundleId's.

Yes, my app is sandboxed.

Does that mean you plan to deploy via the Mac App Store?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Yes. I'd like it, if possible. I have a few mac apps in the store already. I made this for a personal need but I think it could be interesting for anyone else and I'd like to updoad to the store.

If you’re deploying via the Mac App Store then your options are rather limited. The Mac App Store requires that your app be sandboxed, and per my 2 Oct post there’s only two ways to send Apple events from a sandboxed process:

  • Scripting targets (A)

  • A temporary entitlement (B)

With regards A, AFAIK there’s no scripting target that lets you send the

'quit'
Apple event. And with regards B, my experience is that it’s very hard to convince Apple Review to let you use this.

The only alternative that’s worth exploring is

NSUserScriptTask
. This is allowed in Mac App Store, but it’s intended to be used as a way to build attachable interfaces, that is, where the user can attach their scripts to your app. For example, a mail program might use it to run a script when a message lands in a specific mailbox. It’s not intended to be used as a way to bypass the sandbox.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

First of all, thank you again for answering. That's bad news. I guess I'll have to let this app out of Apple App Store then and try to distribute on my own. It's a rather simple app and it will not worth the effort for sure since I don't expect it would going to get any significant profit anyway.


Thank you, eskimo.