Working around macOS privacy controls

Posted by chetan on January 14, 2022 in computers suck

Problem

You need to run a program (like icalBuddy) which requires access to protected macOS resources like your Calendar, Reminders, or Contacts. When you run it from the terminal, you are prompted as usual and grant access. Later, you try to run that program via some other process and nothing happens or you get some obtuse error.

In my case, I was trying to run icalBuddy to pull my calendar appointments into Obsidian, following Ben’s example. Worked great from the command line but not so much from within Obsidian. The problem, as it turns out, is that the privacy grant applies to the “top most app” which launches the process, in this case iTerm.app, and there’s no way to manually grant access directly to icalBuddy or Obsidian.

Solution

After struggling to find a working solution via lots and lots of github reports of similar problems, I finally found a working solution in this comment. I’m writing up here my full solution here as I’m sure I won’t be the last to run into this.

In simple terms, we create an Automator application which simply runs the program we need with whatever arguments we like. We can even pass extra arguments on the command line. The program is saved as a .app and when executed, the privacy prompts are opened and the grants assigned to our new .app.

1. Open /System/Applications/Automator.app and create a new Application:

automator - new application

2. Search for ‘Run Shell Script’ and drag it into the workflow area:

add new shell script

3. Change the pass input setting and add script:

change input and edit script

Here’s the script for easier copying:

rm -f /tmp/getCalEvents.out
/usr/local/bin/icalBuddy -npn -nc -ps "/: /" -iep "datetime,title" \
    -po "datetime, title" -b "\n\n### " \
    -tf "%H%M" -ic "$1" \
    eventsToday 2>&1 >>/tmp/getCalEvents.out

4. Save the application somewhere, e.g., ~/bin/getCalEvents.app and run it once. You should get the privacy prompts as usual which results in the following access grant:

5. Finally, to integrate it into our application, we create another small wrapper which opens the app and returns the output from the tmp file:

#!/bin/bash
rm -f /tmp/getCalEvents.out
open --wait-apps $HOME/bin/getCalEvents.app --args Calendar
cat /tmp/getCalEvents.out

Save that script to, e.g., ~/bin/getCalEvents and call it from your application.

Comments

Leave a response

Comments