What changes when brew runs as the workbrew account
Petros Amoiridis
On a managed Device, brew no longer runs as the person typing it. Whoever runs a command, Homebrew does its work as workbrew, a service account the Workbrew Agent creates. Most of the time nobody notices. When something does behave differently, it's usually because the account doing the work isn't the one sitting at the Mac. This page explains what follows from that, so the differences are predictable rather than surprising.
It applies to managed Devices. A read-only Device leaves Homebrew with whoever installed it. What changes on a Device when Workbrew manages Homebrew covers the switch from one to the other.
Why a separate account
Plain Homebrew runs as the user who installed it, so that user owns everything under /opt/homebrew. That works for one person on one Mac. It doesn't work once a Mac has several users, some of them Standard Users, and an administrator wants packages installed, upgraded and restricted from the Workbrew Console. Someone has to own the files, and it can't be any one of the people using the Mac.
So Workbrew gives Homebrew an owner of its own. When Workbrew takes over Homebrew on a Device, it hands the Homebrew directories to workbrew. From then on, /opt/workbrew/bin/brew checks that you're allowed to use it, then switches to workbrew before running Homebrew. A Standard User can install a package without being an administrator, and the packages are the same for everyone on the Mac.
There is a second reason, which matters most for services. Software from Homebrew is often new, and much of it listens on the network. Running it as an account that can't read your documents limits what a misbehaving package can reach.
Files belong to workbrew, not to you
Being allowed to run brew is a matter of group membership. Members of workbrew_users and administrators can run it. That membership doesn't give anyone access to the files under the Homebrew prefix. Those belong to workbrew, and brew reaches them by running as workbrew.
So a "permission denied" inside /opt/homebrew is almost always about who owns a file, not about which groups you're in. A common case is a file that some other user still owns, for example because it was created outside brew or survived from before Workbrew took over. ls -l on the path shows the owner. Troubleshooting covers the usual fixes.
Writing to the prefix directly, without brew, fails for the same reason. Tools that install into the Homebrew prefix on their own, such as npm install -g with a Homebrew Node, run into this.
Services run as workbrew too
brew services start without sudo starts the service as workbrew, the same as every other brew command. The service gets workbrew's home, /opt/workbrew/home, as its HOME, and brew services list shows workbrew in its User column. The ~/Library/LaunchAgents it shows is workbrew's, not yours.
For a database or a cache this is what you want. A service that is really part of your own session runs into these limits:
- The service keeps its settings and data under
/opt/workbrew/home. Settings you made in your own home folder are ignored, and the service starts with defaults. - It can't read files that only you can open, such as a folder with mode
700or an encrypted volume you mounted. - It isn't part of your login session, so anything that draws on your screen, like a menu bar app, starts without showing anything.
- Anything that names a user by default names
workbrew. PostgreSQL creates aworkbrewrole rather than one named after you, as How to configure PostgreSQL for local development describes.
There's no switch to run one service as you. For a service that needs your account, How to run a Homebrew service as yourself shows how to start it from a LaunchAgent of your own while Homebrew keeps it up to date.
Commands from the Console have no login session
Brew Commands and package installs that come from the Workbrew Console run in the background, through the Workbrew Agent, as workbrew. That account never logs in, so Homebrew sees no one at the screen, even when you are.
Most of the time this doesn't matter. It shows up when Homebrew wants to interact with apps. Homebrew skips quitting a running app before an upgrade and says so. When you uninstall a cask from the Console, Homebrew can't remove the app's login item, and it suggests granting Terminal access to System Events. You can't act on that advice from the Console, and the app is still removed. The login item stays behind until someone removes it in System Settings > General > Login Items & Extensions.
When an install seems done but isn't
Two Homebrew behaviors can look like Workbrew problems, because they often show up around the time Workbrew arrives.
A formula can be installed but not linked. brew list shows it, while its command is missing from your PATH. brew doctor lists formulae in this state and suggests brew link <formula>. Add --overwrite if another file already sits where the link should go.
An install that's interrupted partway can leave files behind that make every retry fail the same way. brew reinstall usually clears them. A Brew Command from the Workbrew Console that is still running after 60 minutes is interrupted, which is one way this happens with a large cask.
Related docs
- How to run a Homebrew service as yourself - for a service that needs your own account
- How to configure PostgreSQL for local development - connecting when the role is named
workbrew - Troubleshooting - fixes for permission errors and
PATHissues - What changes on a Device when Workbrew manages Homebrew - what the switch to a managed Device does
- Managed brew access - who may run
brewon a Device - How the Workbrew Agent uses elevated privileges - where root comes in, alongside the
workbrewaccount - Edit Homebrew formulae - write access for people who change formulae or Taps