Private Taps
Petros Amoiridis
Private Taps are Homebrew Tap repositories hosted in private GitHub or GitLab repositories. Workbrew syncs these repositories through a GitHub App installation or GitLab OAuth integration and distributes them to managed Devices.
Repository structure
A repository must meet the following requirements for Workbrew to discover and sync it:
| Requirement | Detail |
|---|---|
| Name prefix | Must start with homebrew- (e.g. homebrew-tools, homebrew-internal) |
| Visibility | Must be private |
| Formula directory | Formula/ (capital F, singular). Other variants such as Formulas/, formula/, or HomebrewFormula/ are not recognized |
| Cask directory | Casks/ (capital C, plural). Other variants such as Cask/ or casks/ are not recognized |
| File placement | Formulae and casks in the repository root are not discovered |
Sync behavior
The Workbrew Console periodically syncs with the GitHub or GitLab API to discover private repositories whose name starts with homebrew-. For each repository, it fetches the latest commit on the default branch and parses the formulae and casks from the directory tree.
The initial sync runs automatically when a Tap is first discovered. After that, package re-syncs only run when an admin clicks Sync Now in the Console. Automatic re-sync does not run for Taps that have already been synced at least once.
How Taps reach Devices
For GitHub Taps, the Workbrew Agent authenticates git operations using the git-credential-workbrew credential helper. See How Workbrew authenticates private Taps for details on the credential flow.
For GitLab Taps, the Console creates an AutoTapCommand that schedules brew tap <name> <git_url> on target Devices. The Agent runs this command, which clones the repository.
Once a Tap is cloned on a Device, the Agent does not re-clone it on subsequent check-ins.
GitLab nested paths
GitLab repositories can live in nested subgroups (e.g. acme/infra/tools/homebrew-utils). Workbrew derives a two-segment Homebrew Tap name from the full path by taking the root namespace and the repository name:
| Repository path | Derived Tap name |
|---|---|
acme/homebrew-tools | acme/homebrew-tools |
acme/infra/tools/homebrew-utils | acme/homebrew-utils |
acme/team-a/homebrew-tools | acme/homebrew-tools |
The full repository path is stored separately and used for GitLab API calls and clone URLs.
If two repositories in different subgroups derive the same Tap name (e.g. acme/team-a/homebrew-tools and acme/team-b/homebrew-tools), only the first is synced. See Tap name collisions below.
Known constraints
Default branch changes
If the default branch of a Tap repository is changed after a Device has already cloned it, the Device retains the old branch. Running brew untap --force <tap-name> on the affected Device removes the stale clone. The --force flag is required when packages from the Tap are currently installed. The Tap is re-cloned on the next sync cycle, and Homebrew re-associates the installed packages with it.
Untapping with installed packages
brew untap refuses to remove a Tap if formulae or casks from that Tap are currently installed. brew untap --force <tap-name> overrides this and removes the Tap regardless. Installed packages remain on the Device. Their install receipts still reference the Tap, but the packages cannot be upgraded from it until the Tap is re-cloned.
Disabling vs. removing from Devices
Unchecking a Tap in the Console disables it, which stops future installations on new Devices. It does not remove the Tap from Devices that have already cloned it. There is no remote untap mechanism from the Console.
Tap name collisions (GitLab)
Two GitLab repositories with the same name under different subgroups (e.g. acme/team-a/homebrew-tools and acme/team-b/homebrew-tools) derive the same Tap name (acme/homebrew-tools). Only the first repository encountered is synced. Renaming one of the repositories resolves the collision.
Related docs
- Create a private Tap with a custom formula and cask — step-by-step tutorial for building a Tap from scratch
- Sync and authenticate private Taps with Workbrew — setup instructions for GitHub and GitLab integrations
- How Workbrew authenticates private Taps — how the credential helper and token flow work
- Network requirements — domains that must be reachable for Tap clones and updates