Skip to content

macOS agent.sock: breeze group created but never applied, blocking user-helper IPC #3137

Description

@ToddHebebrand

Reported by semotech in #bugs (Discord, message 1534257683362742472).

Report (PII-redacted):

Thanks — useful. On this 2019 iMac (macOS 14.7.2 / amd64 / agent 0.103.0):

Terminal: matches what we saw (paste reordering). Session drop on launchctl kickstart -k system/com.breeze.agent understood. We'll retest terminal paste after next agent build past 0.103.0.

Helper: User already toggled Screen Recording ON for breeze-desktop-helper (off→on), FDA ON, Admin user, reboot — TCC prompt still returns. LaunchAgent com.breeze.desktop-helper-user crash-looped (runs≈133, last exit 1). When run manually as jingxie we got:

  • screenRecording=false / captureGranted=false (ScreenCaptureKit timeout) even while Settings showed the toggle ON
  • accessibility=true, fullDiskAccess=true
  • fatal: dial unix ".../Breeze/agent.sock": permission denied
  • sock was srw-rw---- root:admin — chmod 666 let us proceed; after reboot sock likely recreated tight again
  • from Breeze root PTY, launchctl kickstart/bootstrap on gui/<uid>/… returns 125 Domain does not support specified action (Aqua domain not manageable from agent terminal)

Will pull "/Library/Application Support/Breeze/desktop-helper.log" next. Questions:

  1. Intended agent.sock mode/owner for user-session helper? admin-only 660 breaks non-admin (and we still saw denied before chmod).
  2. Known issue where Screen Recording toggle shows ON but helper still reports screenRecording=false until a GUI-session restart of the helper (not reboot alone)?
  3. Recommend path when gui launchctl returns 125 from remote terminal?

Filed automatically by @breeze-discord triage. Verify and add labels/repro as needed.

Triage analysis

The macOS agent IPC socket permission model is broken for exactly the case the reporter hit: a non-root user-session helper connecting to /Library/Application Support/Breeze/agent.sock. broker_unix.go's setupSocket() chmod's the socket to 0660 (owner+group only) but never chowns it — the group stays whatever the root launchd process's default primary group is (not breeze). Both real install paths — the DMG postinstall script (agent/installer/macos/postinstall) and the programmatic breeze-agent service install path (service_cmd_darwin.go -> ensureDarwinBreezeGroup) — only create the breeze group; neither ever chowns the config dir/socket to root:breeze, nor adds any user to that group. Contrast with agent/scripts/install/install-linux.sh, which both chowns /var/run/breeze to root:breeze AND auto-adds every logged-in user to the breeze group. So on macOS, unless an admin manually runs dscl . -append /Groups/breeze GroupMembership <user> (only documented as a manual step in the standalone bash installer, not the shipped DMG flow), no console user — admin or not — is in the socket's owning group, so LOCAL_PEERCRED-gated 0660 perms deny them, matching the reporter's observed srw-rw---- root:admin, permission-denied dial, and the fact chmod 666 was needed to proceed (and would reset on next agent restart since setupSocket() re-chmods to 0660 every start).

Affected code

  • agent/internal/sessionbroker/broker_unix.go:12-37 — setupSocket() chmods dir 0755 and socket 0660 on every start but never chowns either to a group that real users belong to
  • agent/internal/agentapp/service_cmd_darwin.go:235-238,610-633 — ensureDarwinBreezeGroup() only dscl-creates the 'breeze' group; no chown of CONFIG_DIR/socket, no user added
  • agent/installer/macos/postinstall:15-33,68-69 — Shipped DMG postinstall: same gap — creates breeze group, never wires it to the socket or any user
  • agent/scripts/install/install-linux.sh:126-172 — Contrast: Linux installer chowns IPC dir to root:breeze and auto-adds every logged-in user to breeze group — the macOS equivalent step is missing

Potential fix

On macOS, chown the socket (or its parent dir with setgid) to root:breeze in setupSocket()/service install, and either auto-add the console user to the breeze group at helper-bootstrap time (mirroring install-linux.sh) or document the manual dscl step in the DMG/postinstall flow, not just the standalone bash installer.

Triage analysis, affected code, and fix sketch above were produced by automated investigation (@breeze-discord). Verify before relying on them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions