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

Barkeep's window listing two updates waiting. Rectangle 2.0.4 is cooling off: it will be installed after 27 October, with a deadline of 3 November.

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, Docker, ChatGPT, Claude, Tailscale, Obsidian, UTM and more 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's window listing four apps, each with the way it updates: Firefox from a JSON feed, Rectangle from Sparkle, Visual Studio Code from Squirrel, and Barkeep from its vendor.
Each app with the feed it updates from.
$ 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.

Firefox's details in Barkeep: updated from 158.0 to 158.0.1, found in Barkeep's catalog, with the expected team 43AQ936H96 matching the installed app's Team ID.
An update is installed only if it's signed by the same developer team as the app it replaces.

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 week (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 two weeks after the update was 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.
Barkeep installing Firefox 158.0.1, with the date it was found, when it could install, and its deadline.
An update installing, with when it was found and its deadline.

Nothing hidden from the people using the Mac

Barkeep.app sits in the menu bar and says what's waiting, and when.

Barkeep's menu bar popover: all 4 monitored apps are up to date.
Up to date
Barkeep's menu bar popover: 2 updates waiting, Firefox after 1 November and Rectangle after 27 October.
Updates waiting, and when they'll install
Barkeep's menu bar popover while Firefox installs and Barkeep checks for updates.
Installing

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, and there are examples for locked-down, fast-patching and never-interrupt setups. 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.