MacOS – Is it possible to allow usage for an app or program for a specific times on a Mac

applicationsmacosparental-controlspermission

I was trying to achieve this using a second account (which is the admin account) and Parental Controls, but it seemed this isn't possible to do so.

I know there are some programs which you can download that help you with this, (Cold Turkey, for example). But, it would be much easier if I could do this using only tools already available on macOS.

Best Answer

You can do this with two built in tools:

  • Gatekeeper to allow/disallow access to apps (I've written about it in this post)
  • Launchd to handle the schedule

Gatekeeper

Using Gatekeeper, we can create "rules" that allow you to block/enable apps. Using your example, we can create a list of Apps that is only allowed to run on Fridays:

spctl --add --label "FridayApps" /Applications/SomeApp.app 

The benefit of this, is that you can add multiple apps with the same label and enable/disable them in one single command:

sudo spctl --disable --label "FridayApps"   <---- For Saturday thru Thursday
sudo spctl --enable --label "FridayApps"    <---- For Friday

Launchd

For this you will need a simple script to enable/disable the apps and you need to run this as a daemon (needs sudo privilege) so it has to reside in /Library/LaunchDaemons.

I used the naming convention com.user.FridayApps.plist and FridayApp.sh for the script.

Bash Script:

#!/bin/bash

DOW=$(date +%u)   # Sets the Day of Week; 5 = Friday
TOD=$(date +%T)   # Sets the time of Day
start="12:00:00"  # Sets start time   
end="23:59:00"    # Sets end time

if [ $DOW -eq 5 ]
then
    if [[ "$TOD" > "${start}"  &&  "$TOD" < "${end}" ]]
    then
      /usr/sbin/spctl --enable --label "FridayApps"
    fi
else
    /usr/sbin/spctl --disable --label "FridayApps"
fi

Launchd .plist

<?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.user.FridayApps</string>
    <key>ProgramArguments</key>
    <array>
        <string>/User/MyName/script/location/FridayApps.sh</string>

    </array>
    <key>StartCalendarInterval</key>
    <!--  Weekdays are 1 - 5; Sunday is 0 and 7   -->
    <array>
        <dict>
            <key>Weekday</key>
            <integer>5</integer>
            <key>Hour</key>
            <integer>12</integer>
            <key>Minute</key>
            <integer>01</integer>
        </dict>

        <dict>
            <key>Weekday</key>
            <integer>6</integer>
            <key>Hour</key>
            <integer>00</integer>
            <key>Minute</key>
            <integer>00</integer>
        </dict>
    </array>

</dict>
<key>RunAtLoad</key> 
<true/>
</plist>

##Load the `.plist`

sudo launchctl load com.user.FridayApps.plist

How this works

What's happening here is two things:

  • launchd is running a script twice. Once at the time to run it on and another time to turn it off
  • a simple bash script to turn on/off the enabled app. It verfies the date and then runs the appropriate command