I’ve had success using Homebrew in a multi-user environment the following way:
Create a new (non-GUI) user, group and home directory:
sudo /usr/sbin/sysadminctl -addUser brew \
-fullName 'Homebrew' -admin -home /var/brew \
-password - -UID 430 \
&& sudo createhomedir -c -u brew \
&& sudo dscl . -create /Users/brew IsHidden 1 \
&& sudo dseditgroup -o create -r 'Homebrew group' brew
sudo dseditgroup -o edit -a "$(whoami)" -t user brew
Repeat the command line for others who should have access to the brew
user, too.
sudo bash -ex << 'EOF'
cd "$(mktemp -d)"
echo > brew_group 'Defaults: %brew env_keep -= "HOME MAIL"'
echo >> brew_group
echo >> brew_group 'Defaults: %brew env_keep += "BASH_SILENCE_DEPRECATION_WARNING"'
echo >> brew_group
echo >> brew_group '# Keep all HOMEBREW_* environment variables except for'
echo >> brew_group '# HOMEBREW_BAT_CONFIG_PATH, HOMEBREW_CACHE, HOMEBREW_CLEANUP_MAX_AGE_DAYS,'
echo >> brew_group '# HOMEBREW_LOGS and HOMEBREW_TEMP'
echo >> brew_group 'Defaults: %brew env_keep += "all_proxy"'
echo >> brew_group 'Defaults: %brew env_keep += "ftp_proxy"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_ARCH"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_ARTIFACT_DOMAIN"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_AUTO_UPDATE_SECS"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_BAT"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_BINTRAY_KEY"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_BINTRAY_USER"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_BOTTLE_DOMAIN"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_BREW_GIT_REMOTE"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_BROWSER"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_COLOR"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_CORE_GIT_REMOTE"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_CURL_RETRIES"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_CURL_VERBOSE"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_CURLRC"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_DEVELOPER"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_DISABLE_LOAD_FORMULA"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_DISPLAY_INSTALL_TIMES"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_DISPLAY"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_EDITOR"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_FAIL_LOG_LINES"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_FORCE_BREWED_CURL"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_FORCE_BREWED_GIT"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_FORCE_HOMEBREW_ON_LINUX"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_FORCE_VENDOR_RUBY"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_GIT_EMAIL"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_GIT_NAME"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_GITHUB_API_PASSWORD"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_GITHUB_API_TOKEN"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_GITHUB_API_USERNAME"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_INSTALL_BADGE"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_MAKE_JOBS"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_NO_ANALYTICS"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_NO_AUTO_UPDATE"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_NO_COLOR"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_NO_COMPAT"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_NO_EMOJI"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_NO_GITHUB_API"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_NO_INSECURE_REDIRECT"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_NO_INSTALL_CLEANUP"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_PRY"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_SKIP_OR_LATER_BOTTLES"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_SVN"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_UPDATE_TO_TAG"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_VERBOSE_USING_DOTS"'
echo >> brew_group 'Defaults: %brew env_keep += "HOMEBREW_VERBOSE"'
echo >> brew_group 'Defaults: %brew env_keep += "http_proxy"'
echo >> brew_group 'Defaults: %brew env_keep += "https_proxy"'
echo >> brew_group 'Defaults: %brew env_keep += "no_proxy"'
echo >> brew_group
echo >> brew_group '%brew ALL = (brew) NOPASSWD: ALL'
chown root:wheel brew_group
chmod 440 brew_group
visudo -c -s -f brew_group
mkdir -p /private/etc/sudoers.d
SUDO_EDITOR="tee" visudo -f /private/etc/sudoers.d/brew_group < brew_group
echo Success
EOF
On Intel (or Apple Silicon with Rosetta 2):
sudo chown -R brew:admin /usr/local/*
On Apple Silicon:
sudo chown -R brew:admin /opt/homebrew
The brew
user needs a bit of customization so it’s easier to use.
Customizing the prompt is convenient because it helps you figure out e.g. whether you are in the brew
user or not.
For example, add the following lines to /var/brew/.bashrc
or /var/brew/.zshrc
:
function nonzero_return() {
RETVAL=$?
[ $RETVAL -ne 0 ] && echo "[$RETVAL]"
}
export -f nonzero_return
export PS1="[\u] \w \`nonzero_return\`"$'\xf0\x9f\x8d\xba'" "
Add the following line to /var/brew/.bashrc
or /var/brew/.zshrc
:
(Caution: For a native Apple Silicon Homebrew installation, use /opt/homebrew
instead of /usr/local/
.)
export PATH='/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin'
Add the following lines to /var/brew/.bashrc
or /var/brew/.zshrc
:
__homebrew_cask_config_path="${HOMEBREW_REPOSITORY:-$(
brew --repository)}/Library/Homebrew/cask/config.rb"
if [ -e "${__homebrew_cask_config_path}" ]; then
IFS=$'\n' read -a '__homebrew_cask_options' -d '' <<< "$(sed -n \
-e 's#^ *\([a-z_]*dir\): *"~\(.*\)",#--\1="\2"#p' \
"${__homebrew_cask_config_path}"
)" || true
HOMEBREW_CASK_OPTS=''
for __homebrew_cask_option in "${__homebrew_cask_options[@]}"; do
HOMEBREW_CASK_OPTS=`
`"${HOMEBREW_CASK_OPTS:+${HOMEBREW_CASK_OPTS} }"
HOMEBREW_CASK_OPTS=`
`"${HOMEBREW_CASK_OPTS}${__homebrew_cask_option}"
done
unset __homebrew_cask_config_path __homebrew_cask_option \
__homebrew_cask_options
export HOMEBREW_CASK_OPTS
fi
Anyone who is in the brew
group can now enter the brew shell without requiring a password:
sudo -u brew -s
While in the brew
shell, you can use the brew
command without restriction.
You can leave the brew
shell again by pressing ^+D.