Bit of an odd one. Our organisation needs to allow some aspect of local storage access to accommodate work on large files without constantly writing to network drives. They work on these files and then copy them to mounted AD drives. I want to restrict the local files that can be written to. My solution has been to create a launchagent that hides all default folders using chflags hidden and schg on the first login of a user. I have used a launchagent because of the impending threat of login hooks being removed. The issue is that Documents and Downloads never have either the hidden or immutable flag applied and I have no idea why. I have added a delay before the script is run, added the script to the sudoers file so it can be run as root, changed the code, killed finder and kept it killed for the script duration, and even made the script just try to hide documents and nothing works. Any suggestions would be appreciated.

FYI I have tried

find ~ -maxdepth 1 -mindepth 1 -type d -not -name '.*' -not -path "*/Library" -not -path "*/Desktop" -exec sudo chflags schg {} \; -exec sudo chflags hidden {} \;

sudo chflags hidden $HOME/Documents

sudo chflags hidden ~/Documents

sudo chflags -R hidden $HOME

edit: Forgot to mention that manually running the script with the exact same parameters after login works and successfully hides the Documents and Downloads folder. It has to be something on login.

  • Does it work for other folders?
    – nohillside
    Jun 25, 2021 at 10:58
  • Yep, works for every default folder (Movies, Pictures, etc) just not Documents and Downloads.
    – Auspexis
    Jun 25, 2021 at 11:06
  • Which macOS version are you running?
    – nohillside
    Jun 25, 2021 at 11:06
  • Also, under which user account does the launchctl job run?
    – nohillside
    Jun 25, 2021 at 11:07
  • OSX 11 Big Sur. And it is a plist in /library/launchagents. It runs for everyone. It is called by the user on login, but i have used a postinstall script to add the script to sudoers using visudo so it can run with sudo privileges.
    – Auspexis
    Jun 25, 2021 at 11:15

1 Answer 1


Ok, I have solved this and I will explain the answer fully if anyone has a similar issue.

There are certain times when you will need to run a start script/event as sudo. You can do this using LaunchDaemons which are run as sudo at system boots and are run outside of a specific user session. However, there are times where you may want to run something as sudo in user context. To resolve this, I initially had a plist that called an executable script with sudo as an argument, ie sudo path/to/script/script.sh

The script was added to visudo during the postinstall of the agent, and looked like %everyone ALL = (ALL) NOPASSWD: /Library/Scripts/script.sh. Do not do this. I only go into such detail because to me it seems like the most logical way to go about it. Plists act oddly when parsing the sudo parameter.

Instead, don't bother making the script executable with chmod +x and leave its permissions 700 if it is sensitive. Add a visudo command with the bash/sh parameter like %everyone ALL = (ALL) NOPASSWD: /bin/sh /Library/Scripts/script.sh.

Next, and most importantly create a secondary initialiser script that will call the main script. Call the main script with sudo. This script will need at least 755 permissions. In the Plist, call the initialiser script using no parameters other than bash/sh.

Overall, the process should be:


echo '%everyone ALL = (ALL) NOPASSWD: /bin/sh /Library/Scripts/script.sh' | sudo EDITOR='tee -a' visudo


<?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">

Initialiser script:

sudo sh /Library/Scripts/script.sh 

Main script:

Whatever you want

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .