<!--
SPDX-FileCopyrightText: (c) 2026 brew-proxy contributors <https://codeberg.org/HastD/brew-proxy>

SPDX-License-Identifier: Apache-2.0 OR MIT
-->

# brew-proxy

brew-proxy is a DBus-activated service that facilitates configuring a
[Homebrew](https://brew.sh/) installation on Linux more securely.

Typically, a Homebrew installation is owned by the user who initially set up
Homebrew. This is convenient but has security disadvantages:

- Any unsandboxed process run by that user can arbitrarily modify the Homebrew
  installation, including any installed executables.
- Homebrew build/install scripts have access to the user's files except to the
  extent that such access is prevented by sandboxing. Homebrew did
  [recently add sandboxing on Linux](https://brew.sh/2026/06/11/homebrew-6.0.0/#-linux-sandbox);
  however, the Linux sandboxing relies on unprivileged user namespaces, which
  have been associated with a number of security vulnerabilities, and are
  therefore disabled on some systems for security.

Additionally, standard Homebrew installations don't work well with multi-user
setups, as other users don't have the ability to manage the Homebrew
installation at all.

brew-proxy provides a different permissions model for a Homebrew installation
that's more secure and works better on multi-user systems.

## Permissions model

With brew-proxy, the `/home/linuxbrew` directory is configured to be
world-readable but writable only by a dedicated `linuxbrew` system user. This
means that commands that modify the Homebrew installation or Homebrew packages
must be run as the `linuxbrew` user. This provides a security boundary in two
directions:

- Unauthorized users cannot modify the Homebrew installation or packages.
- Homebrew package install scripts do not have access to other users' home
  directories.

To make it more convenient for authorized users to manage the Homebrew
installation, brew-proxy provides a DBus-activated service, `brew-proxy-daemon`,
that runs on demand as the `linuxbrew` user, executing `brew` commands on behalf
of authorized users.

Any user can run the provided `brew-proxy` command, which accepts `brew`
commands and forwards the request over DBus to `brew-proxy-daemon`. The daemon
is integrated with Polkit and requires the user to authenticate for certain
commands:

- Informational commands that do not modify the brew installation (such as
  `brew list`, `brew info`, `brew search`, and so on) can be run by all users
  without authentication.
- Certain maintainence commands like `brew update`, `brew upgrade`, and
  `brew cleanup` can be executed without authentication by users in the
  `brewadmin` or `linuxbrew` groups. Other users must authenticate as an
  administrator to run these commands.
- Other commands that modify the brew installation (including any commands that
  install or uninstall packages) can be executed without authentication only by
  users in the `linuxbrew` group.

To run non-interactively, run the client with the environment variable
`BREW_PROXY_NONINTERACTIVE=1` set. In this mode, access is automatically denied
if authentication would be required. This can be useful, for example, if a brew
command is invoked in a service running in the background.

When running multiple commands in a row that modify the Homebrew installation,
it may be convenient to instead run `run0 -u linuxbrew` to start a shell as the
`linuxbrew` user.

## Installation

An RPM package built from the specfile at `brew-proxy.spec` is available in a
[Copr repo](https://copr.fedorainfracloud.org/coprs/amaranth/homebrew/).

Alternatively, you can manually compile and install brew-proxy as follows:

1. Clone this git repository.
2. Run `meson setup build -Dprefix=/usr` and `meson compile -C build` from the
   repository root.
3. Install the project with `meson install -C build`.

## Setup

To patch your Homebrew installation so that `/home/linuxbrew` is owned by the
`linuxbrew` user and `brew` commands run by users other than `linuxbrew` are
automatically forwarded to `brew-proxy`, run the script at
`/usr/libexec/brew-proxy/brew-proxy-setup.sh` as root. For convenience, a
systemd service, `brew-proxy-setup.service`, is also provided that runs this
script once. (An opt-out is provided: if the environment variable
`NO_BREW_PROXY=1` is set, `brew-proxy` will be bypassed.)

Additionally, if you want a user to be able to run Homebrew maintainence
commands without authenticating, add them to the `brewadmin` group.

If you want a user to be able to run _any_ Homebrew command without
authenticating, you can add them to the `linuxbrew` group. This is a security
degradation and is not recommended.

## Additional notes

- brew-proxy is not an official part of Homebrew and does not claim to be
  endorsed by the Homebrew developers.
- brew-proxy does not isolate parts of the Homebrew installation from each
  other; that is, Homebrew package install scripts can still arbitrarily modify
  the Homebrew installation.
- The brew-proxy daemon runs the requested brew commands in a PTY and passes a
  file descriptor of the PTY over DBus back to the client who requested the
  command. The client can cancel a running command by pressing Ctrl+C in the
  terminal to interrupt the process by hanging up the PTY.
