Barkeep

Every Mac app updates itself.
Just not when you need it to.

Each app has its own idea of updating: some check on launch, some ask for an admin password, some wait for the user to click a button they've learned to ignore. Your vulnerability report doesn't care whose idea it was.

Barkeep keeps the bar. It runs in the background, works out how each app updates, and installs the update while the app is closed, after it's been out long enough to trust. Nobody gets interrupted unless a deadline you set says they must.

macOS 27+ · Apple silicon · Intune, Jamf, Kandji and other MDMs

Knows how apps update

Most apps already publish their updates somewhere. Barkeep reads the same feed they do.

Sparkle

The appcast in the app's SUFeedURL, with the EdDSA signature the app's own key expects. Channels, minimum macOS and delta-only items handled.

Electron and VS Code

electron-builder's latest-mac.yml (GitHub, generic or S3) with its SHA-512, and the Squirrel-style API in VS Code's product.json with its SHA-256.

A catalog, and yours

Chrome, Firefox, Zoom, Slack, Discord and Docker are built in. Add anything else in the profile: a GitHub repository, an appcast, or any URL that says what's newest.

Knows its limits

App Store apps and apps with their own enterprise updater (Microsoft AutoUpdate, Adobe) are reported, not fought over. Apple's own apps are left to Software Update.

$ barkeep inspect "/Applications/Visual Studio Code.app"
Update source:  Squirrel (catalog) https://update.code.visualstudio.com
Newest:         1.143.1, released 21 Oct 2026 at 10:15
Checksums:      SHA-256
Update?:        yes

No fake updates

A feed can be hijacked. A signature from the same developer can't be faked.

Same developer

The new copy must be signed by the Apple-verified Team ID of the copy it replaces, and satisfy that copy's designated requirement: the same rule macOS uses to decide two builds are the same app.

Same app, and newer

Same bundle ID, a higher version, built for this Mac's macOS and Apple silicon. No downgrades, however the feed is dressed up.

Same bytes the vendor signed

HTTPS only, size-limited, and matched against any checksum or Sparkle EdDSA signature in the feed. Gatekeeper has to agree it's notarised.

Checked where it's installed

Every check runs on a root-owned staged copy beside the app, which is then swapped in atomically. What's verified is exactly what gets installed.

Packages too

Updates shipped as .pkg must be signed by the app's own team and notarised, and the app they leave behind is checked again afterwards.

Locked configuration

Settings come from a managed profile users can't change. Root-owned files only.

Polite, until it can't be

The best time to update an app is when nobody is using it.

  1. Cooling-off. An update waits until it has been out for a day (you choose), so the vendor's bad release is somebody else's Tuesday.
  2. Quietly, while closed. The moment the app isn't running, it's swapped for the new version. While that takes, the app can't be opened half-updated: open it, and it reopens a moment later. That hold expires on its own, so a failed update never locks anyone out.
  3. Deadline. Still open a week after the update was found, or released? The user gets a notification, an hour's grace, then the app is asked to quit, exactly as if they'd chosen Quit, so it can ask to save. It reopens when it's done.

Simple to run

One package, two profiles, no scripts per app.

  1. Deploy the package. It installs /usr/local/bin/barkeep, the daemon that does the work, and Barkeep.app for the menu bar. Don't want the app? barkeep-cli.pkg leaves it out.
  2. Deploy the profiles. The settings profile spells out every default, so it's safe unchanged. The App Management profile lets barkeep replace other developers' apps and pre-approves its notifications.
  3. Watch it work. barkeep status, the log at /Library/Logs/barkeep.log, or Barkeep.app's window.
$ barkeep status
Firefox.app 150.0 → 158.0.1 [waitingForQuit] Firefox 158.0.1 will be installed when it quits, or by 31 Oct 2026 at 09:12
Slack.app 4.52.182 [upToDate] Slack.app 4.52.182 is up to date
Zoom.app 7.1.0 (60000) → 7.2.2.88465 [coolingOff] will be installed after 25 Oct 2026 at 14:00

Know the limits

Barkeep updates apps that can be updated by replacing the app, or by the vendor's signed package. It doesn't sign in to the App Store for anyone, can't update an app whose feed it can't find (tell it in the profile), and on a cold-blooded deadline it asks apps to quit; only if you say so does it insist. The README covers the trade-offs in full.