When your screen turns off, does your Mac ask you for your password when you wake it back up? It’s pretty easy to check, just lock the screen, and wake it up.
What if you aren’t in front of the computer? What if you needed to check this across your entire organization’s Mac fleet? What if you wanted to manage this behavior? I have some bad news. Starting with High Sierra (10.13), these objectives may no longer be possible.
In High Sierra this is the state of affairs related to the screensaver password:
There is no remote method to determine if the feature is turned on.
You have to be careful with you how craft the profile payload to enforce it.
This blog will explain how we got here, and what you can do to mitigate this issue until Apple responds with a fix.
A common practice for the screensaver setting on macOS in enterprise environments is to enforce an acceptable maximum delay before the screen locks, but give the user permission to maintain a lower value if needed. For example, the policy might allow for 10 minutes of idle time before prompting for the password, but the user can keep the default value of 5 minutes, or even lower it to zero if they choose.
In order to enforce the 10 minute threshold, you would need to periodically
query and reset the setting. The simplest way, is by running
defaults read com.apple.screensaver askForPassword to get the value,
and then likely immediately followed by a
defaults write command if the
current value is above the threshold.
More advanced utilities use the CFPreferences API with python or Objective-C to read the value from the system. That’s exactly what the Osquery agent does to populate the preferences table. Understanding the hierarchy of values in CFPreferences can be complex, but Osquery does a great job of abstracting that complexity away.
SELECT * FROM preferences WHERE domain="com.apple.screensaver" AND key="askForPassword" AND username="victor";
Using the above query you could run it with
osqueryi to get the required
values, or schedule it with
osqueryd to periodically log the results of
the query and send them to a centralized server. Based on the values being
read by osquery, the server could then decide to enforce the acceptable
10 minute idle delay if the user was out of compliance.
With the introduction of Mobile Device Management (MDM), Apple provided Configuration Profiles as a method to enforce settings on macOS and iOS. While there are other options, Apple has strongly encouraged profiles delivered through MDM as the configuration distribution mechanism.
To manage the screensaver preference with a profile, we have to craft an XML payload that looks roughly like this:
<dict> <key>PayloadDisplayName</key> <string>Security and Privacy</string> <key>PayloadEnabled</key> <true/> <key>PayloadIdentifier</key> <string>com.acme.config.screensaver</string> <key>PayloadUUID</key> <string>966eb7be-81bd-f8cc-f3e3-078d93f1b4a4</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadType</key> <string>com.apple.screensaver</string> <key>askForPassword</key> <true/> </dict>
Though this XML is verbose, the important takeaway is that it manages
com.apple.screensaver preference domain using a key identical to the
one enforced by CFPreferences (typically,
Apple uses the CFPreferences API to read and write configuration values).
It is important to note when querying profiles that osquery uses a different
table to query enforced configuration (
managed_policies) than user defined
preferences). So if you’re an osquery user querying macs,
you usually have to run two or more queries to get an
accurate state for preferences:
managed_policiestable for the domain and key you’re interested in. If the key exists, that is the enforced value on the system, nd therefore the effective value. If you get 0 results from the host, it means the value is not enforced, but it still might be set.
preferencestable, adding the user whose preferences you’re looking for as a JOIN column. If the user sets a value other than the system default, it will be returned here.
With the rollout of High Sierra across our fleet,
it became obvious that osquery was failing to read
the screensaver values correctly.
At first we were concerned this was a regression in osquery.
Querying CFPreferences through
defaults read helped us determine that
was not the case. No data seems to be available through any API.
While trying to figure out how to query for the configuration, we ran into an
inexplicable problem: Somehow we got the computer in a state where the
profile was on the system and CFPreferences told us the
key was enforced, but the screensaver wouldn’t actually come on and the
checkbox in the System Preferences security tab remained unchecked.
So our profile was not enforced, and the screensaver lock was completely disabled, although osquery and any other tool we tried told us that the value was enforced. This was so odd that I created a new VM to test further. After going through the same steps and resetting the VM, I confirmed what I already suspected: The profile is broken. I now had enough to file a bug report. The profile does work sometimes, so depending on your workflow you may or may not experience this issue.
If the profile is installed immediately during device bootstrap, the profile enforces the defined setting and the screensaver lock works as expected.
But, if the user has a chance to set their own preference before the profile is applied, the profile has no effect at all. Installing the profile does not override the user’s configuration, but it does lock them out of the ability to change it for themselves.
askForPasswordDelay key to the profile helps to remediate the
profile, but only slightly. The actual preference only appears to be
synced after the user logs in again.
We’ve seen this situation before. As recently as the release of
macOS 10.12 (Sierra) the
HomePage key in
com.apple.Safari became impossible
to query. Apple had moved the homepage preference to the Local Items keychain
defaults read was no longer able to access it. I reached out to
Michael Lynn, a fellow Mac admin whose
done a lot of work exploring various
system APIs and has valuable insights into troubleshooting macOS system APIs.
Michael suggested I log out of the current user,
and using another admin account, delete the current user’s Local Items keychain.
After following Michael’s advice and deleting the affected user’s keychain, I logged back in as that user and noted that my broken profile was fixed and enforcing the expected behavior. Great!
The bad news is that while we solved the mystery of how this value is stored, deleting the user’s local keychain is not a viable solution or workaround.
Taking a step back, this situation is just a symptom of the massive upheaval and changes to the security architecture of macOS and Mac devices.
This is a good thing, and while Apple should be applauded for attempting to innovate the security model of macOS, users and organizations can only benefit if it’s done in a responsible manner.
Apple clearly has a plan for how to manage Macs and macOS fleets and that plan definitely includes heavy reliance on MDM. Unfortunately, the intent of their decisions is confusing when they move settings to the keychain where tools like osquery can no longer inspect their values but simultaneously introduce bugs that prevent the management and inspection of that same setting via the MDM API.
While this situation in isolation isn’t damning, this is just another datapoint in a recent pattern of behavior. For example:
Apple pushed forward User Approved Kernel Extensions, without a way for enterprises to configure a whitelist (hopefully fixed in 10.13.2)
A rewrite of Disk Utility introduced a security flaw in the password hint mechanism.
Going forward, Apple’s constant iteration on security mechanisms introduces risks to operators, but tools like osquery can help us remain vigilant and identify these issues earlier.
Until Apple resolves this bug, screensaver security/lock settings must be managed carefully. More specifically:
Enforce the profile ASAP, during initial bootstrap.
Make sure the
askForPasswordDelaykey is used in the profile.
If you’re affected by this or similar changes, I recommend Michael Lynn’s talk from MacDevOpsYVR earlier this year.