Homebrew Package Policies and Supply Chain Protection
Homebrew includes central configuration, package restrictions and explicit trust for third-party taps. Use these features to make your organisation’s normal Homebrew workflow follow a reviewed policy. Your management system distributes the settings and your existing help desk or Git workflow handles approvals. Operating-system controls remain necessary when the requirement is to prevent an untrusted user from executing software.
The configuration works on macOS and Linux; cask settings apply only on macOS.
Run the Homebrew commands as the prefix owner.
For root management jobs, use the absolute brew path with as-brew-user, for example /opt/homebrew/bin/brew as-brew-user config on Apple Silicon.
- Set central configuration with
brew.env - Deploy a central package policy
- Choose the restriction that matches the requirement
- Separate tap trust from package approval
- Resolve group policies and exceptions before deployment
- Use mirrors without weakening verification
- Apply operating-system execution rules
- Apply separate controls to other package ecosystems
- Handle release delays and urgent fixes
Set central configuration with brew.env
Homebrew reads environment files in this order:
| Scope | Location |
|---|---|
| System | /etc/homebrew/brew.env |
| Prefix | $HOMEBREW_PREFIX/etc/homebrew/brew.env |
| User | ~/.homebrew/brew.env, or the homebrew/brew.env file under the configured XDG directory |
Later files override earlier files.
Set HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY=1 in /etc/homebrew/brew.env to load that file again last, overriding conflicting prefix and user settings.
The user file is resolved using the selected account’s home and configuration directory.
See the environment reference for XDG configuration and all available variables.
-
Create a reviewed
brew.envin your configuration repository, substituting your help-desk details:HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY=1 HOMEBREW_FORBIDDEN_OWNER=IT support HOMEBREW_FORBIDDEN_OWNER_CONTACT=https://support.example.com/homebrewWrite literal
NAME=valuelines, withoutexportor surrounding shell quotes. Values can contain spaces, but shell expansion and command substitution are not supported. Use1to enable a setting and omit unwanted settings;0is not a general way to disable booleans. - Deliver that file to
/var/tmp/homebrew-config/brew.envwith your management system’s file or package delivery. Make this staging directory and file root-owned and writable only by administrators. -
Install the prepared file as root, readable by the managing account:
/usr/bin/install -d -o root -g "$(/usr/bin/id -gn root)" -m 0755 /etc/homebrew /usr/bin/install -o root -g "$(/usr/bin/id -gn root)" -m 0644 \ /var/tmp/homebrew-config/brew.env /etc/homebrew/brew.env -
Inspect the effective settings as the Homebrew owner:
brew configConfirm the expected
HOMEBREW_settings appear, then follow the package-policy checks before deploying restrictions more widely.
Prefix and user files are useful for account-specific defaults. The prefix owner can normally modify prefix configuration, so use the system file for centrally maintained settings. These settings control Homebrew behaviour; they do not prevent the owner from modifying Homebrew itself or executing software outside it.
Deploy a central package policy
- Choose restrictions from the table below and record the policy owner and exception process.
- Prepare a reviewed
brew.env, replacing the example packages and help-desk address with your choices:
HOMEBREW_SYSTEM_ENV_TAKES_PRIORITY=1
HOMEBREW_FORBIDDEN_FORMULAE=telnet
HOMEBREW_FORBIDDEN_CASKS=transmission
HOMEBREW_FORBIDDEN_TAPS=example/unreviewed
HOMEBREW_FORBID_PACKAGES_FROM_PATHS=1
HOMEBREW_FORBIDDEN_OWNER=IT support
HOMEBREW_FORBIDDEN_OWNER_CONTACT=https://support.example.com/homebrew
- Follow the central configuration deployment steps to install the file on a pilot device.
- Inspect the effective configuration and test the intended restrictions before assigning more devices.
Space-separated lists replace earlier values rather than automatically merging across device groups.
Choose the restriction that matches the requirement
| Requirement | Setting or workflow | Scope and limitation |
|---|---|---|
| Block named command-line tools | HOMEBREW_FORBIDDEN_FORMULAE |
Includes formula dependencies; does not remove existing installations |
| Block named applications | HOMEBREW_FORBIDDEN_CASKS |
Includes cask dependencies; does not block a direct vendor download |
| Block a package source | HOMEBREW_FORBIDDEN_TAPS |
Use the remote URL when a tap uses a custom remote |
| Refuse local package definitions | HOMEBREW_FORBID_PACKAGES_FROM_PATHS |
Refuses formula and cask file paths in Homebrew |
| Restrict formula licences | HOMEBREW_FORBIDDEN_LICENSES |
Uses declared SPDX metadata, including formula dependencies |
| Explain policy failures | HOMEBREW_FORBIDDEN_OWNER and its contact |
Directs users to the team that owns the restriction |
| Control third-party Ruby loading | brew trust and brew untrust |
Trust is explicit but can be changed by the managing account |
Inspect effective settings as the Homebrew owner:
brew config
Test restrictions against direct installs and dependencies, since a newly introduced dependency can also block an upgrade.
For licence policies, use SPDX identifiers such as HOMEBREW_FORBIDDEN_LICENSES=AGPL-3.0-only; the declared formula licence is not a complete component inventory and casks have no equivalent field.
Separate tap trust from package approval
Tap trust protects against loading non-official package definitions without an explicit trust decision. Trust individual formulae, casks or commands when that is sufficient; whole-tap trust covers current and future contents. Official taps are trusted by default.
Tap trust is not an administrator-controlled allowlist of everything a developer may install. The managing account can grant trust, including by installing a fully qualified package name. A Brewfile is also a desired software baseline, not an allowlist: packages absent from it can still be installed.
For an approved-only catalogue, use a dedicated Homebrew owner and fixed installation actions in your management system.
Users request additions through the self-service approval workflow.
Do not grant arbitrary brew execution as the dedicated owner merely to implement a self-service button.
Users may still download or run software elsewhere unless separate operating-system controls prevent that.
Resolve group policies and exceptions before deployment
Homebrew does not know MDM groups or exception records.
- Resolve group conflicts and approved exceptions into one effective
brew.envper device. - Deploy and verify it using the central configuration steps.
- Find existing restricted packages through inventory; restrictions do not remove them.
- Review their dependants before approving removals, then collect fresh inventory.
Use mirrors without weakening verification
Homebrew supports HOMEBREW_API_DOMAIN, HOMEBREW_BOTTLE_DOMAIN and HOMEBREW_ARTIFACT_DOMAIN for managed download infrastructure.
Set them in central configuration according to the environment reference.
API and bottle mirrors can fall back to their public sources.
HOMEBREW_ARTIFACT_DOMAIN_NO_FALLBACK=1, used with HOMEBREW_ARTIFACT_DOMAIN, stops artefact downloads when that mirror cannot supply them.
Git repositories, advisory queries and vendor installers may need separate network access. Mirrors do not replace device-wide network controls or package verification.
For compatible casks, HOMEBREW_CASK_OPTS=--require-sha requires a checksum.
Use HOMEBREW_NO_SUDO=1 when your policy forbids Homebrew from invoking privileged installers, and deliver applications that require them through the MDM instead.
Provision private-tap credentials as described in the fleet guide; plain-text brew.env files are not a secret-management service.
Configure firewall and proxy access
- Allow the destinations required by your actual packages and configured mirrors, including HTTPS redirects:
| Operation | Typical destinations |
|---|---|
| Package metadata | formulae.brew.sh or your configured API mirror |
| Bottles and portable Ruby | ghcr.io and its download destinations, or your mirror |
| Homebrew and tap updates | github.com and your private Git hosts; SSH if you chose SSH remotes |
| Source and cask downloads | The upstream hosts in the selected packages’ URLs and redirects |
| Vulnerability matching | api.osv.dev, formulae.brew.sh, raw.githubusercontent.com and, where needed, repology.org |
This is a starting point, not a complete static domain allowlist.
-
Test metadata, package and advisory access on a pilot device.
brew update brew fetch git brew vulns --json -
Review diagnostics and permit the necessary redirects before expanding deployment.
Retain diagnostics when a proxy or firewall denies a request; do not disable TLS or checksum verification to make downloads succeed. Configure proxy settings for the unattended account, not just an administrator’s interactive shell; see the proxy environment variables. Your MDM agent has its own network requirements and may not support the same proxy configuration as Homebrew.
Apply operating-system execution rules
Package restrictions govern Homebrew operations; use operating-system controls when the requirement is to prevent execution of software downloaded through any route. For Macs, follow the binary execution rules, accounting for interpreters, package updates and signing identities.
Apply separate controls to other package ecosystems
Installing a runtime with Homebrew does not route its later downloads through Homebrew’s policies or vulnerability scanner.
For project dependencies, use controls such as npm audit, pip hash checking and OSV-Scanner.
Use your MDM to distribute the applications’ own extension controls, such as Chrome’s ExtensionSettings, Firefox’s ExtensionSettings and VS Code’s allowed-extension policies.
These controls govern supported applications; they do not make Homebrew a scanner for extensions or project dependencies.
Homebrew does not provide a network inspection proxy, runtime malware detector or AI usage monitor.
Handle release delays and urgent fixes
HOMEBREW_AUTO_UPDATE_SECS controls metadata refresh timing, not a minimum upstream release age.
Use staged patch-management jobs for Homebrew updates.
For language dependencies, pnpm’s minimum release age and uv’s release cutoff apply to their own resolvers.
See Homebrew Security and Supply Chain for Homebrew’s review, build and distribution protections.