| name | mac-onboarding |
| description | Export macOS app configs and settings from source Mac, install on target Mac without Time Machine or cloud sync |
| tags | ["macos","dotfiles","configuration","bootstrap","mdm-safe","tailscale"] |
mac-onboarding
Fast, privacy-first macOS configuration exporter and installer. One script, one command—migrate your entire Mac environment to a new machine without Time Machine, iCloud, or cloud backups.
When to Use
- Setting up a new Mac — restore apps, dotfiles, settings, hotkeys from your old Mac
- MDM-managed Macs — works safely on corporate machines (respects enrollment and protected defaults)
- Privacy-sensitive environments — all secrets redacted, nothing to cloud
- Bridging Macs — pull configuration live from source Mac via Tailscale SSH (no archive needed)
- Reproducible setups — version your onboard.yaml in git, repeat fresh installs identically
NOT for: Migrating user data (photos, documents, mail), password managers (separate process per app), SSH keys (add manually), Time Machine replacement.
What It Captures
| Category | What's Exported | Install Behavior |
|---|
| Package managers | Homebrew (via brew bundle dump) | brew bundle install |
| Shell | zsh/bash rc files, oh-my-zsh custom | Secrets redacted, configs restored |
| Git | .gitconfig, .gitignore_global, .config/git/ | Credential helpers redacted |
| Code editors | Cursor, Claude Code, Codex, pi.dev | Settings, keybindings, extensions, AI tokens redacted |
| Terminal | Kitty full config | Full restore |
| System | Dock, Finder, keyboard repeat, trackpad, screenshot location | MDM-safe allowlist |
| Hotkeys | Global shortcuts via com.apple.symbolichotkeys | Full restore, pbs daemon restarted |
| Apps | SwiftBar, Alfred, Klack, f.lux, BetterDisplay, OrbStack, Tailscale, Shottr, Synology | Plist restore (⚠️ audit Alfred for credentials) |
| Cloud tools | 1Password | Setup guide only (security) |
Quick Start
1. Export (Source Mac)
git clone https://github.com/oleg-koval/mac-onboarding.git
cd mac-onboarding
make build
sudo mv dist/mac-onboarding /usr/local/bin/
cp onboard.yaml.example onboard.yaml
nano onboard.yaml
mac-onboarding export --dry-run ~/onboard.tar.gz
mac-onboarding export ~/onboard.tar.gz
2. Install (Target Mac)
scp onboard.yaml target-mac:~/onboard.yaml
scp source-mac:~/onboard.tar.gz ~/
mac-onboarding install --dry-run ~/onboard.tar.gz
mac-onboarding install ~/onboard.tar.gz
3. Bridge Mode (Live Pull — No Archive)
echo "source:" > onboard.yaml
echo " host: source-mac.tailscale.com" >> onboard.yaml
mac-onboarding bridge pull --dry-run
mac-onboarding bridge pull --only brew,shell
mac-onboarding bridge pull
Configuration
onboard.yaml (copied from onboard.yaml.example):
source:
host: your-mac-hostname
modules:
bootstrap:
skip: false
brew:
skip: false
options:
brewfile_path: ~/.Brewfile
shell:
skip: false
options:
redact_pattern: "export .*(KEY|TOKEN|SECRET|PASSWORD|API)=.*"
git:
skip: false
system:
skip: false
hotkeys:
skip: false
All paths support ~ and $HOME expansion.
Usage Patterns
Pattern 1: Archive Export/Install
Typical for USB transfer, email, cloud storage:
mac-onboarding export ~/onboard-$(date +%Y%m%d).tar.gz
mac-onboarding install ~/onboard.tar.gz
Pattern 2: SSH Piping (No Archive)
Direct streaming via SSH:
ssh user@source-mac "mac-onboarding export --to-stdout" | \
mac-onboarding install --from-stdin
Pattern 3: Bridge Mode (Live Pull)
Fastest for single modules:
mac-onboarding bridge pull --only brew,shell
mac-onboarding bridge pull
Requires:
source.host in onboard.yaml
- Tailscale running on both Macs
- Same username on both Macs
Pattern 4: Selective Modules
Skip unwanted modules:
modules:
brew:
skip: true
onepassword:
skip: true
Or CLI:
mac-onboarding export --only shell,git ~/minimal.tar.gz
mac-onboarding install --only shell,git ~/minimal.tar.gz
mac-onboarding bridge pull --only kitty,cursor
Dry-Run First
Always test before applying:
mac-onboarding export --dry-run ~/test.tar.gz
mac-onboarding export ~/test.tar.gz
mac-onboarding install --dry-run ~/test.tar.gz
mac-onboarding install ~/test.tar.gz
Security
By design:
- Secrets redacted before archiving (shell env vars, git credentials, AI tokens)
- No cloud sync—everything stays local or over SSH
- MDM-aware—won't override enrollment or protected defaults
- Offline after initial config—no internet required
Before open-sourcing:
- Review
onboard.yaml for any API keys you missed
- Audit exported archive:
tar tzf onboard.tar.gz
- Test credential redaction:
grep -i token onboard.tar.gz should show no real values
- Check Alfred sync folder for embedded credentials
What's NOT captured:
- SSH private keys (add to ~/.ssh manually)
- Password manager data (1Password, Bitwarden handled per app)
- Cloud credentials (prompted during install)
- Large caches, logs, sessions
Troubleshooting
| Issue | Solution |
|---|
config: no onboard.yaml found | Copy onboard.yaml.example to onboard.yaml and edit |
| Module skip not working | Check YAML indentation (spaces not tabs) |
| Secrets leaked in archive | Review shell.redact_pattern and test: tar xzOf onboard.tar.gz shell/.zshrc | grep -i token |
| MDM won't let system defaults install | Some domains (Dock, Finder) are protected—check logs for which ones failed |
| Bridge pull fails | Verify source Mac's Tailscale hostname in config; run tailscale status on source |
| Hotkeys not applied | Restart System Preferences or restart Mac (pbs daemon is auto-restarted) |
| Homebrew install fails | Ensure Xcode CLT is installed first (bootstrap module handles this) |
Requirements
- macOS 11+ (Big Sur or later)
- Tailscale (for bridge mode, optional otherwise)
- Homebrew (bootstrap module installs it)
- Git (to clone repo;
make build requires Go)
Building Locally
make build
make test
make lint
make release
make install
make clean
CI/CD
Automated tests and releases via GitHub Actions:
- test.yml — runs on every push/PR: go test, go vet, staticcheck, fmt check
- release.yml — runs on every push to
main: increments and pushes the latest patch version tag, builds Intel + Apple Silicon binaries, creates a GitHub release with checksums, and updates the Homebrew tap formula
Release prerequisites:
Examples
Scenario: Fresh Mac Setup
mac-onboarding export ~/my-setup.tar.gz
scp /Volumes/USB/my-setup.tar.gz ~
mac-onboarding install ~/my-setup.tar.gz
Scenario: Team Standardized Setup
git clone https://github.com/company/mac-setup.git
cd mac-setup
mac-onboarding export ~/standard.tar.gz
tar tzf ~/standard.tar.gz | head -20
git clone https://github.com/company/mac-setup.git
cd mac-setup
mac-onboarding install ~/standard.tar.gz
Scenario: Minimal Dotfiles Only
mac-onboarding export --only shell,git ~/dotfiles.tar.gz
mac-onboarding install --only shell,git ~/dotfiles.tar.gz
Scenario: Bridge Pull from Remote Mac
source:
host: old-mac.tailscale.com
mac-onboarding bridge pull --only kitty,cursor
Privacy Checklist
Before sharing onboard.yaml or archive:
License
MIT
Contributing
Issues and PRs welcome. Before contributing, read CONTRIBUTING.md (coming soon).
Contact
GitHub Issues