GitHub - travisvn/stop-tahoe-update: Prevent your Mac from "upgrading" to Tahoe. A community-led effort to safely block unwanted macOS upgrades.

4 min read Original article β†—

πŸ›‘ Stop Tahoe Update

A community-led effort to delay, suppress, and safely block unwanted macOS upgrades (e.g. Sequoia β†’ Tahoe).

License: MIT Contributions Welcome GitHub Discussions Build & Validate

Safe β€’ Transparent β€’ Community-driven
Everything here is reversible and off by default.


βš™οΈ Why This Project Exists

Apple allows deferring major macOS upgrades (like Sequoia β†’ Tahoe) for up to 90 days using MDM or configuration profiles.
Beyond that, users are on their own β€” exposed to constant upgrade prompts, badge counts, and surprise downloads.

Stop Tahoe Update exists to change that responsibly.
We’re building a community-maintained source of truth for users who want to stay on stable macOS versions without unsafe hacks.


🎯 Project Goals

βœ… Immediate Goals

  • Provide .mobileconfig profiles for 30 / 60 / 90-day deferrals
  • Include safe install / uninstall / status scripts
  • Establish a safety-first governance model
  • Build and maintain a living documentation hub

🧠 Community Research Goals

  • 🚫 Prevent β€œInstall Tonight” or β€œInstall Now” prompts
  • πŸ”• Suppress Settings app badge counts for new macOS upgrades
  • πŸ›‘οΈ Detect & optionally remove unwanted Install macOS*.app downloads
  • 🌐 Explore early network-detection of upgrade payloads (opt-in)
  • 🧩 Track new Apple deferral keys & declarative MDM behavior

All experimental features are dry-run by default.
No background services, no silent system modifications.


πŸ—‚οΈ Repository Structure

stop-tahoe-update/
β”œβ”€ profiles/                 # 30, 60, 90-day deferral .mobileconfig files
β”œβ”€ scripts/                  # Safe install/uninstall/status scripts
β”œβ”€ plugins/                  # Optional "shield" experiments
β”‚  β”œβ”€ installer-watcher/     # Detect & alert on rogue installers
β”‚  └─ update-signal-monitor/ # Early-warning system log monitor
β”œβ”€ docs/                     # Goals, RFCs, research, compatibility
└─ .github/                  # Governance, CI, review workflows

πŸ”¬ Active Experiments

Plugin Type Description Default
Installer Watcher LaunchAgent Detects /Applications/Install macOS*.app and offers to move it to Trash Dry-run
Update Signal Monitor LaunchAgent Monitors unified logs & prefs for upgrade preparation signals Dry-run

Both run in user space, never require sudo, and write audit logs under ~/Library/Logs.


🧭 Roadmap

Phase Description Status
Phase 1 30/60/90-day deferrals + safety scripts βœ… Done
Phase 2 Fallback shields (Installer Watcher, Signal Monitor) 🚧 In progress
Phase 3 Badge & prompt suppression research πŸ” Community testing
Phase 4 Declarative + network-layer experiments πŸ§ͺ Future

🧩 Vision & Philosophy

  • Transparency over magic: Every line of code is inspectable and reversible
  • Safety first: No background daemons, no automatic actions
  • Community-led: Every installable artifact is review-gated
  • Apple-aligned: Start with supported deferral keys, innovate cautiously beyond them

πŸ§‘β€πŸ’» Contributing

We welcome:

  • 🧱 Developers – build and test optional shields
  • πŸ” Researchers – document macOS update behavior
  • πŸ§ͺ Testers – verify reproducibility across versions
  • 🧭 Reviewers – audit scripts and profiles for safety

πŸ“„ See CONTRIBUTING.md and docs/GOALS.md.


🧰 Quick Start

1. Clone or download the repo

git clone https://github.com/travisvn/stop-tahoe-update.git
cd stop-tahoe-update

Ensure the scripts are executable

# Ensure scripts are executable (just in case)
chmod +x ./scripts/*.sh

2. Apply a 90-day deferral profile

The script will generate unique identifiers to prevent conflicts and attempt to install the profile.

./scripts/install-profile.sh profiles/deferral-90days.mobileconfig

Note

On recent macOS versions, silent installation may be blocked. If the script opens System Settings, please locate the "Profiles" (or "Downloaded Profile") notification and click Install manually to complete the process.

3. Verify status

4. Remove later if needed

./scripts/uninstall-profile.sh

πŸ” What the deferral profiles actually do

They use Apple’s official com.apple.applicationaccess keys:

<key>forceDelayedMajorSoftwareUpdates</key><true/>
<key>enforcedSoftwareUpdateMajorOSDeferredInstallDelay</key><integer>90</integer>

These settings hide major upgrades from Software Update for up to 90 days. After that, the OS may begin prompting again.


βš–οΈ Safety & Governance

  • 🧾 Signed releases only β€” no curl | sh install methods
  • 🧱 CodeOwners required for profiles/, scripts/, and plugins/
  • πŸ§ͺ CI validation: XML linting, ShellCheck, SHA-256 hash checks
  • πŸ›‘οΈ No root operations unless clearly documented & user-initiated
  • πŸ”’ Security disclosure policy: see SECURITY.md

πŸ—ΊοΈ Beyond Tahoe

While this repo focuses on Sequoia β†’ Tahoe, the long-term goal is a more general toolkit: StayOnMac β€” empowering macOS users to choose when (or if) they upgrade.

Future versions may include:

  • Broader version targeting (Sonoma, Ventura, etc.)
  • GUI wrappers for non-technical users
  • Integration with open MDM tools

πŸ’¬ Community & Support

  • πŸ’­ GitHub Discussions: share findings, theories, and test results
  • 🧩 observations tag: submit verified upgrade triggers or logs
  • 🧠 RFCs: propose new shields via docs/rfcs/

🧾 License

MIT License β€” simple, permissive, and open. All contributions must remain verifiable, reversible, and user-controlled.