auditctl is a small CLI over the same analyzer the app uses. Useful for
scripting, for CI, and for the one thing the GUI can’t easily do: checking an
update before you install it.
Building it
auditctl is not shipped in the DMG. Build it from a checkout:
Usage
<target> is either a path to a .app or a substring of an app name, so
auditctl fire will find Firefox.
Run bare on a terminal, auditctl opens an interactive browser. With stdin or
stdout redirected it prints usage instead, which keeps it safe in CI.
Auditing one app
There is no risk-tier filter here —
--min-tier belongs to preview, and
auditctl exits 2 on any flag it doesn’t recognise.
Previewing updates
preview is the interesting subcommand. With no arguments it looks at your
outdated Homebrew casks and audits what you’re about to receive:
brew is looked for at $HOMEBREW_PREFIX/bin/brew if that variable is set,
then /opt/homebrew/bin/brew and /usr/local/bin/brew. If none of them is
executable, preview exits 2 and says so — --all-apps skips Homebrew
entirely and reads /Applications and ~/Applications directly.
With --fetch, it downloads the incoming cask build and diffs it against the
version you have installed — so you can see what an update adds before taking
it:
preview will not upgrade anything. It never runs brew upgrade and
never blocks or delays an update — it will not get between you and your
package manager.It does run brew, though. In cask mode — the default — every invocation
shells out to brew outdated --cask --json=v2; only if that comes back with
something outdated does a second call to brew info --cask --json=v2 follow,
so on an up-to-date machine you pay for outdated alone. Neither call is
timed out. --fetch adds brew fetch --cask <token>, which downloads the
incoming artifact into Homebrew’s cache. And it exits 0 on success but 2 on
failure, including when Homebrew isn’t installed at all. Account for both
before you wire it into a shell prompt or a pre-upgrade hook.The --fetch caveat
With --fetch, an incoming build is analysed before Gatekeeper has assessed
it. A freshly downloaded artifact can therefore show a one-off “notarization”
difference that is an artefact of the download rather than a real change in the
app. The output flags this where it applies — read it before drawing
conclusions.
.dmg and .zip cask artifacts are understood. .pkg is skipped.