From 251ebd6e5bfe747a1d9f83a49abf6d393ee4aee1 Mon Sep 17 00:00:00 2001 From: Igor Soarez Date: Thu, 1 Oct 2026 21:10:47 +0300 Subject: Brewfile: say what the two taps actually ship Checked rather than assumed. QuickMD is signed with a Developer ID and notarized, so its quarantine flag costs a dialog. toggleMute is ad-hoc signed with no TeamIdentifier, and spctl rejects it as modified since signing -- so the quarantine step is not 'it is not notarized' but 'there is no verifiable publisher'. The trust gate also turned out looser than the first note claimed: it refused an untrusted formula, but both casks installed without it. --- install.sh | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'install.sh') diff --git a/install.sh b/install.sh index 3ee3f67..4351357 100755 --- a/install.sh +++ b/install.sh @@ -51,12 +51,16 @@ if [[ "$(uname)" == "Darwin" ]]; then >&2 echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"' exit 1 fi - # Two casks in the Brewfile come from their authors' own taps, and brew - # refuses to load a cask from an unofficial tap until it is trusted. Trust is - # per machine, recorded in $XDG_CONFIG_HOME/homebrew/trust.json, so it cannot - # live in the Brewfile; naming the casks rather than the taps keeps the trust - # to these two files instead of everything the taps ever add. Older Homebrews - # have no `trust` subcommand and need nothing, hence the guard. + # Two casks in the Brewfile come from their authors' own taps. Homebrew gates + # unofficial taps behind `brew trust`, recorded per machine in + # $XDG_CONFIG_HOME/homebrew/trust.json, so it cannot live in the Brewfile. + # Measured on 2026-10-01 rather than assumed: the gate refused an untrusted + # *formula* outright, while these two casks installed through brew bundle + # without it and only quickmd ended up recorded. So this is a precaution that + # keeps working if the gate tightens, not a step the install depends on + # today. Naming the casks rather than the taps keeps the trust to these two + # files and not whatever the taps add later. Older Homebrews have no `trust` + # subcommand and need nothing, hence the guard. if brew help trust >/dev/null 2>&1; then for untrusted_cask in satrik/togglemute/togglemute b451c/quickmd/quickmd; do brew trust --cask "${untrusted_cask}" >/dev/null || \ @@ -80,13 +84,20 @@ if [[ "$(uname)" == "Darwin" ]]; then >&2 echo fi - # toggleMute is not notarized, so Gatekeeper refuses to open it while the - # download carries com.apple.quarantine, and the author's install - # instructions say to clear it. Only that one attribute, not the `xattr -cr` - # the README asks for, which strips every extended attribute the app has. - # Nothing here can vouch for the binary: this is a deliberate exception for - # one app, which is why it names the path rather than looping over - # /Applications. + # toggleMute will not open while the download carries com.apple.quarantine, + # and the author's install instructions say to clear it. What that costs is + # worth stating exactly, because it is worse than "not notarized" (checked + # 2026-10-01): the app is ad-hoc signed, TeamIdentifier is not set, and + # `spctl -a` rejects it with "invalid Info.plist (plist or signature have + # been modified)". There is no verifiable publisher, and macOS considers the + # bundle altered since it was signed. Clearing quarantine is the only way to + # run it, so this is a deliberate exception for one app -- hence the explicit + # path rather than a loop over /Applications, and only that one attribute + # rather than the `xattr -cr` the README asks for, which would strip every + # extended attribute the bundle has. + # + # QuickMD needs none of this: it is signed with a Developer ID and notarized, + # so its quarantine flag costs one dialog and nothing more. togglemute_app="/Applications/toggleMute.app" if [[ -d "${togglemute_app}" ]] && xattr "${togglemute_app}" 2>/dev/null | grep -q com.apple.quarantine -- cgit v1.2.3