Core Principle
macOS (Ventura+) surfaces all launchd agents in System Settings > Login Items. When an agent’s ProgramArguments[0] is /bin/sh and the binary isn’t codesigned by an identified developer, macOS displays it as “sh from unidentified developer”. The AssociatedBundleIdentifiers plist key tells macOS which app to attribute the agent to, fixing the display.
Why This Matters
Nix - Home Manager wraps launchd agents in /bin/sh -c \"/bin/wait4path /nix/store && exec <binary>\" to block until the Nix store is mounted at boot. This is the correct pattern (the alternative, KeepAlive.PathState, causes launchd to penalize the service if the path isn’t available at launch time). But it means every HM agent shows as “sh” in Login Items.
Evidence/Examples
Home Manager’s launchd module has freeformType = attrsOf anything, so arbitrary plist keys are accepted without upstream changes:
-- For apps with a real bundle ID
launchd.agents.aerospace.config.AssociatedBundleIdentifiers = \"bobko.aerospace\";
-- For CLI tools, associate with a parent app (e.g., the terminal)
launchd.agents.atuin-daemon.config.AssociatedBundleIdentifiers = \"com.mitchellh.ghostty\";The AssociatedBundleIdentifiers key accepts a string or array of strings. The bundle must be installed on the system or macOS may still show “unidentified developer”.
After changing plists, the cached BTM database needs resetting: sudo sfltool resetbtm followed by a reboot. Caveat: this also clears “Open at Login” items, which don’t auto-restore. Dump first with sudo sfltool dumpbtm > ~/Documents/btmdump.txt.
Implications
- Any Nix-managed launchd agent on macOS benefits from this pattern
- CLI tools without bundles should be associated with whichever app “owns” them conceptually (terminal emulator, IDE, etc.)
- This is a presentation fix only; it doesn’t affect codesigning or Gatekeeper behavior
Related Ideas
Questions
- Will Apple eventually require codesigned binaries for launchd agents, breaking Nix store paths entirely?
- Should Home Manager add
AssociatedBundleIdentifierssupport as a first-class option rather than relying on freeform attrs?