MacOS – How to run AppleScript (.scpt) as LaucnDaemon by root

applescriptlaunchdmacos

I have an AppleScript or set of Applescripts that I am trying to run as a LaunchDaemon. I have no problem running the LaunchDaemon with my user. The problem comes in where I have the need to read a file that is only readable by root, this is by design for security reasons as the file contains sensitive information.

I have installed the necessary precompiled AppleScript files, the .scpt files, in:

/Library/Scripts/myApplication/

I have put my plists under:

/Library/LaunchDaemons

Edit:
Here is the plist for my Daemon:

<?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>Label</key>
    <string>com.mycompany.myapp.service</string>
    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
    <key>ProgramArguments</key>
    <array>
      <string>/usr/bin/osascript</string>
      <string>/Library/Scripts/myApp/myApp.scpt</string>
    </array>
</dict>

Now, when I try to load the plists using launchctl and sudo

sudo launchctl load -w /Library/LaunchDaemons/com.mycompany.myapp.service.plist

I get errors in the systemlog.log:

Aug 26 17:54:13 computername com.apple.xpc.launchd[1] (com.mycompany.myapp.service[74757]): Service exited with abnormal code: 1
Aug 26 17:54:13 computername com.apple.xpc.launchd[1] (com.mycompany.myapp.service): Service only ran for 0 seconds. Pushing respawn out by 10 seconds.

However if I drop the "sudo" from the launchctl command it works perfectly. I have even tried running the scripts from the terminal as the root user, which also works fine. However, as soon as I try to load them with launchctl and sudo everything dies.

In order to get this script to run previously I had to give the application running the script accessibility privileges on the machine, so previously Sublime Text 2, Terminal and Script Editor. I am guessing that this what is causing the script to not run but I do not know which program to enable under accessibility, since I am not being prompted. So how do I get this script to run the way I need it to?

Best Answer

Assuming your launchd job is correctly set-up, you may be reaching a limitation of AppleScript.

AppleScript Requires a GUI (Aqua Session)

If your AppleScript is launched using launchd as a user root process, it will not have a graphical user interface associated. The majority of AppleScript requires a graphic user interface to work consistently. Depending on the version of OS X, it may work, but it is not designed to.

Processes on OS X can not trivially cross between user sessions.

Do Shell Script

A more robust approach is to separate out the functionality needing higher privileges into a shell script such as bash, perl, ruby, or python.

Your AppleScript can then call that script using AppleScript's do shell script:

do shell script "command" user name "me" password "mypassword" with administrator privileges

If you need to avoid embedding a username and password, this is possible but beyond the scope of this question.