MacOS – How to make macOS require the password once per day, before Touch ID

macbook promacospasswordSecuritytouch-id

My Mac is configured with Touch ID and most of the time I want that, but I want to configure a policy such that the first time I wake it up after 6 AM it requires my password, or such that it requires my password once every 24 hours.

Is that possible? If so, how?

Best Answer

If you've not already set your security preferences to require a password after some amount of sleep and/or screensaver, there's really no benefit to forcing a login at the beginning of the day - it's been vulnerable all that time and locking it at 6:00am only to be unlocked again for the rest of the day makes it a moot security policy.

But, if you want to force an authentication event every day at 6:00am you'll need to do the following:

  • write a bash script that locks the computer. There are two methods...

    • pmset
    • CGSession
  • have that script run every day at a prescribed time using launchd

A note about the scripts/terminal commands

  • I encourage you to test them out first before handing them over to launchd. Just type out the command(s) in Terminal to see if they work.

  • You must set the script to be executable by using the command chmod +x <nameofscript> or this won't work at all.


Using pmset

Assuming that you have "Require Password" after some amount of time after you lock the screen or activate your screen saver, you can use the following command in a bash script to sleep your computer once per day:

pmset sleepnow

The script can be saved in ~/Library/Scripts and can be called whatever you like. Let's use sleep1.sh for this example

#!/bin/bash
# 
/usr/bin/pmset sleepnow

Run that script and your Mac will immediately go to sleep and if you have a password set, depending on the time interval you set, once you wake it, it will ask you for a password.


Using CGSession

This uses the "Fast User Switching" mechanism to lock your desktop. You can test it out by issuing the following command:

/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend

When you execute this command, your desktop will be locked and you should be greeted with a login screen where you have to select a user (if you have multiple) or enter a username and password.

The script, like the previous example can be saved in ~/Library/Scripts and can also be called whatever you like. Let's use sleep2.sh for this example.

#!/bin/bash
#
# Get User ID
id=$(id -u <username>

# Put the system to sleep but switch to current user
/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend -switchToUserID $id

Note: If you intend to do this for all logged in users (if you have multiple users on your machine), change the id line to look like this:

id=$(id -u `whoami`)

This will ensure that the command uses the user id of the currently logged in user.


Using launchd to make this run every day

To get this to run every day, we need to have an daemon kick it off at a prescribed time. macOS comes with such a tool and it's called launchd. I go into further detail about it in the post launchd plist format for running a command at a specific time on a weekday. However, for our purposes here, we'll use a basic .plist to start this script every morning. I like to use the file naming convention com.user.XXXX.plist Replace "XXX" with whatever you like, for this example, I'm using com.user.lockmachine.plist.

Also be sure to reference the script you plan to use, script1.sh or script2.sh

<?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.lockmachine</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/<username>/Library/Scripts/script1.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
      <key>Hour</key>
      <integer>6</integer>
      <key>Minute</key>
      <integer>0</integer>
    </dict>
</dict>
</plist>

How do you want to run this daemon?

Where you put the script matters. See the linked post for more details, but decide if you want this to be for just you or for all users. Here's a quick summary:

  • Just you - put it in ~/Library/LaunchAgents
  • For all users - put it in /Library/LaunchAgents

Then from the directory where you put the newly created .plist, load it using launchctl

sudo lauchctl load com.user.lockmachine.plist

Authenticate away!

You're done. Once per day at 6AM your machine will be forced to go to sleep or have the session switched (depending on the script you selected) where you'll be forced to authenticate. There's no point in doing this on login or at boot because if you're this concerned about security, you wouldn't have auto login enabled bypassing authentication.