The latest tagged release is the only supported version. macrift is small and moves fast; older calver tags do not receive backports.
If you find a security issue in macrift itself — for example, an unsafe
defaults write path, a permission-escalation hole in the install script, or a
plugin-loader escape — please do not open a public issue.
Email stone.mail.dev@gmail.com with:
- a one-line summary
- the macrift commit (or tagged version) that's affected
- a reproducer or proof-of-concept
- your suggested fix if you have one
You should hear back within 72 hours. I'll work with you on a private branch, ship the fix as a patch release, and credit you in the release notes if you want.
The plugin system is the area of macrift with the largest attack surface. This section documents what plugins can do, what macrift protects against, and what it cannot.
A macrift plugin runs arbitrary bash with the user's privileges. By running
macrift plugin add <url> the user grants the plugin:
- Read access to
$HOME, including~/.ssh/, browser profiles, keychain dumps, shell history, anything else under the user's home - Write access to anything the user can write
- The ability to install Homebrew formulas and casks, run
defaults write, load launchd jobs, and run sudo prompts (the user will still see the OS password dialog, but a plugin can ask for it)
This is the same trust model as Homebrew taps, oh-my-zsh plugins, vim plugins, and VS Code extensions. macrift does not pretend to sandbox plugins, because sandboxing arbitrary bash on macOS is essentially impossible.
-
Required version pinning is recommended.
macrift plugin add <url>@<git-tag-or-sha>is the documented form. Without a pin the user accepts upstream'sHEADon everymacrift plugin update. -
Pre-install review. macrift shows the plugin's README and the last 10 commits of the plugin's repo before running any of the plugin's code, and explicitly prompts for confirmation.
-
Lint warnings for risky patterns.
macrift plugin lintflags:- raw
defaults writeoutsideaudit_default(breaks undo, and lets a plugin make changes invisible to the journal) - raw
launchctl bootstrapoutside the provided helpers (same reason) - writes outside
~/.macrift/plugins/<name>/and$HOME-rooted paths the plugin owns curl | bashat runtime (un-pinnable, un-auditable)- re-defining macrift's public API functions
A plugin can still install despite lint warnings — we can't enforce them at runtime — but
macrift plugin infowill surface the findings to the user. - raw
-
Trusted-list mechanism (planned). A curated set of plugins maintained by the macrift team.
macrift plugin add --trusted <name>will skip the pre-install prompt for entries on that list. Entries are admitted only after a manual code review.
- A plugin that uses macrift's audit primitives correctly but does something malicious in handler logic the lint cannot reason about.
- A plugin that calls out to
curlagainst an attacker-controlled URL at runtime, even if not piped tobash. - Supply-chain compromise of a previously-trusted plugin upstream — the plugin's git history is shown at install time, but a malicious commit can be styled to blend in.
- Rogue
lifecycle.on_installscripts. They run after the user's confirm prompt; the prompt is the trust boundary.
If you don't recognize the author and the plugin is not on the trusted list,
read menu.sh and the files under handlers/ before installing. The plugin's
git history is on screen for a reason.
macrift core mutates the user's system in three places that warrant separate attention:
-
defaults writeviaaudit_default. Every change is queued and journaled before application. The journal records (domain, key, type, value, prior value) soapply_audited_defaultsis reversible. Failure modes: the prior value can benull(key didn't exist), which is recorded and handled on undo. -
Marker-block rc-file mutations (
~/.zshrc,~/.bashrc,~/.config/fish/config.fish). All writes go through helper functions that bracket their inserts with sentinel markers and refuse to operate on a file with unbalanced markers (_cc_marker_balancedguard). Failure mode: a user manually editing inside a marker block can corrupt it; macrift refuses to touch the file in that case rather than guessing. -
launchd plist install / bootstrap. Plists are written to
~/Library/LaunchAgents/, validated withplutil -lint, and bootstrapped vialaunchctl bootstrap gui/$UID. Failure modes: a bootstrap that fails (label collision, malformed plist) is reported but does not abort the calling menu (guarded by|| true).
config/claude-code/hooks/security-gate.sh is a PreToolUse(Bash) hook for
Claude Code that blocks dangerous shell patterns (piped remote execution,
eval/exec with command substitution, git push --force/-f, secret
exfiltration via curl/wget interpolating env vars named
*TOKEN/*SECRET/*KEY/*PASSWORD).
The hook is a defence-in-depth backstop, not a guarantee. Regex-based
command filtering cannot block every variant of a dangerous command
(bash -c "$(curl …)", base64-encoded payloads, file-then-execute). The
permission allow-/deny-list in settings/user.json is the primary control;
the hook closes a few common holes the prefix-matched list cannot see.
If you find a bypass that should be blocked, the reporting flow at the top of this file applies.