| 1 |
<?xml version="1.0" encoding="UTF-8"?> |
| 2 |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" |
| 3 |
"http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| 4 |
|
| 5 |
ops-agent as an Aqua LaunchAgent on the Mac build host (mbp). |
| 6 |
|
| 7 |
LimitLoadToSessionType=Aqua is load-bearing: it makes the agent run in the GUI |
| 8 |
login security session, where codesign can USE the Developer ID key. A |
| 9 |
LaunchDaemon (session 0) or a plain SSH session can only enumerate the key, |
| 10 |
not sign with it. See _private/docs/ops-core/executor.md "THE WALL". |
| 11 |
|
| 12 |
Install with NO root (loads into your own GUI domain): |
| 13 |
cp work.makenot.ops-agent.plist ~/Library/LaunchAgents/ |
| 14 |
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/work.makenot.ops-agent.plist |
| 15 |
launchctl kickstart -k gui/$(id -u)/work.makenot.ops-agent # restart after edits |
| 16 |
|
| 17 |
Host prerequisites: auto-login on boot (an Aqua session must exist) and no |
| 18 |
idle sleep (caffeinate / Energy Saver), so the host stays reachable. |
| 19 |
|
| 20 |
<plist version="1.0"> |
| 21 |
<dict> |
| 22 |
<key>Label</key> |
| 23 |
<string>work.makenot.ops-agent</string> |
| 24 |
|
| 25 |
<key>ProgramArguments</key> |
| 26 |
<array> |
| 27 |
<string>/Users/max/.local/bin/ops-agent</string> |
| 28 |
<string>--config</string> |
| 29 |
<string>/Users/max/.config/ops-agent/config.toml</string> |
| 30 |
</array> |
| 31 |
|
| 32 |
<key>RunAtLoad</key> |
| 33 |
<true/> |
| 34 |
<key>KeepAlive</key> |
| 35 |
<true/> |
| 36 |
|
| 37 |
|
| 38 |
<key>LimitLoadToSessionType</key> |
| 39 |
<string>Aqua</string> |
| 40 |
|
| 41 |
|
| 42 |
launchd gives a job only /usr/bin:/bin:/usr/sbin:/sbin. The agent shells |
| 43 |
`tailscale whois` to authorize every caller, and the Tailscale CLI lives in |
| 44 |
Homebrew's prefix (/opt/homebrew/bin on Apple Silicon, /usr/local/bin on |
| 45 |
Intel). Without these on PATH, whois fails, every caller resolves to no |
| 46 |
grant, and the agent answers /health with empty capabilities while denying |
| 47 |
every step it looks up but does nothing. |
| 48 |
|
| 49 |
<key>EnvironmentVariables</key> |
| 50 |
<dict> |
| 51 |
<key>PATH</key> |
| 52 |
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string> |
| 53 |
</dict> |
| 54 |
|
| 55 |
<key>StandardOutPath</key> |
| 56 |
<string>/Users/max/Library/Logs/ops-agent.out.log</string> |
| 57 |
<key>StandardErrorPath</key> |
| 58 |
<string>/Users/max/Library/Logs/ops-agent.err.log</string> |
| 59 |
</dict> |
| 60 |
</plist> |
| 61 |
|