Skip to content

feat(agent,agent-installer): add macOS installer package - #2192

Merged
Marc-André Moreau (mamoreau-devolutions) merged 5 commits into
masterfrom
agent-macos-port
Nov 12, 2026
Merged

Marc-André Moreau (mamoreau-devolutions) merged 5 commits into
masterfrom
agent-macos-port

Conversation

@mamoreau-devolutions

@mamoreau-devolutions Marc-André Moreau (mamoreau-devolutions) commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Enable Devolutions Agent on macOS with separate arm64 and x64 installer packages. Install and start the Agent as a root launchd daemon, keep existing configuration root-only during upgrades, and wait for launchd to unload before replacing or removing package files. PowerShell Universal jobs require Microsoft's macOS PowerShell package; the root daemon does not search Homebrew prefixes. The uninstaller can preserve or purge configuration.

Build, sign, notarize, and publish the packages through the release workflows using the configured Apple credentials.

Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com

Devolutions Agent now ships for macOS as one installer package per architecture.
The package installs the `com.devolutions.agent` launchd daemon, which runs as root, starts at boot, and restarts after a crash.
Installing creates a default configuration when none exists, and upgrading keeps the existing one.
`devolutions-agent-uninstall` removes the Agent, and `--purge` also removes its configuration and logs.
On macOS, `devolutions-agent start` and `stop` act on the installed daemon.

The macOS identity, tunnel, and PowerShell Universal features match Linux.
The Package workflow signs the executable, signs the installer with a Developer ID Installer certificate, and notarizes it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reuse the existing Developer ID Application and Apple notarization
secrets. Add separate Installer certificate secrets for the Agent
package, and verify both architecture binaries and packages in
production.

Fail macOS signing errors and document the required environment
secrets.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 9, 2026 21:53
@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

Let maintainers know that an action is required on their side

  • Add the label release-required Please cut a new release (Devolutions Gateway, Devolutions Agent, Jetsocat, PowerShell module) when you request a maintainer to cut a new release (Devolutions Gateway, Devolutions Agent, Jetsocat, PowerShell module)

  • Add the label release-blocker Follow-up is required before cutting a new release if a follow-up is required before cutting a new release

  • Add the label publish-required Please publish libraries (`Devolutions.Gateway.Utils`, OpenAPI clients, etc) when you request a maintainer to publish libraries (Devolutions.Gateway.Utils, OpenAPI clients, etc.)

  • Add the label publish-blocker Follow-up is required before publishing libraries if a follow-up is required before publishing libraries

@mamoreau-devolutions

Marc-André Moreau (mamoreau-devolutions) commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor Author

Change summary (772c20f, c08a0ff)

  • Production code: package/AgentMacOS/com.devolutions.agent.plist:14 restricts the root daemon PATH to Microsoft PowerShell and system directories. package/AgentMacOS/scripts/postinstall:10-20 rejects symlinks and resets the existing data directory to root:wheel 700 with ACLs removed. package/AgentMacOS/scripts/preinstall:19-22 and package/AgentMacOS/devolutions-agent-uninstall:39-42 abort if launchd does not unload before replacement or removal.
  • Tests: package/AgentMacOS/Test-Package.sh:36-41,49-54 prepares a user-owned 0755 data directory with a broad ACL, then checks the root-only permissions, ACL removal, and daemon PATH. The privileged installation smoke test passed on macOS arm64; full CI run 42916587708 passed on retry after a transient GitHub Actions cache DNS failure.
  • Other files: package/AgentMacOS/README.md:32-33 documents the Microsoft PowerShell package and restricted PATH; .github/workflows/package.yml removes the obsolete installer-signing note.
  • Review: All 3 inline review threads are resolved.
  • UNTESTED: package/AgentMacOS/scripts/postinstall:10-15 symlink rejection and the unload-timeout failure paths in package/AgentMacOS/scripts/preinstall:19-22 and package/AgentMacOS/devolutions-agent-uninstall:39-42 are not exercised by the smoke test. Verify these branches when changing path handling or unload waits.

Note

Human-tuned, LLM-assisted content.

Reference the Developer ID Installer certificate and password under
the names available to the package workflow. Update the signing
documentation to match.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@mamoreau-devolutions Marc-André Moreau (mamoreau-devolutions) changed the title ci(package): verify macOS package signing feat(agent,agent-installer): add macOS installer package Nov 9, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Critical issues permit root execution of user-controlled PowerShell when PSU is enabled and expose credentials through insecure permissions on existing configuration directories.

3 open issues
What changed in this PR

This PR adds macOS Agent installer packages to the build and release pipeline, with production signing and notarization verification for both architectures.

Changes:

  • Add architecture-specific packages, launchd configuration, installation scripts, and lifecycle checks.
  • Sign Agent binaries and packages, notarize packages, and verify production artifacts.
  • Publish macOS packages and document installation and required signing secrets.
File Description
package/​AgentMacOS/​Test-Package.sh Checks installation, service control, upgrade, and removal.
package/​AgentMacOS/​scripts/​preinstall Stops the existing service before payload replacement.
package/​AgentMacOS/​scripts/​postinstall Initializes configuration and loads the daemon.
package/​AgentMacOS/​README.md Documents installation, operation, removal, and packaging.
package/​AgentMacOS/​distribution.xml Defines architecture and OS requirements for the installer.
package/​AgentMacOS/​devolutions-agent-uninstall Removes the service and optionally purges stored data.
package/​AgentMacOS/​com.devolutions.agent.plist Defines the launchd daemon and its environment.
devolutions-agent/​src/​cli.rs Uses the package’s launchd label for macOS service control.
ci/​tlk.ps1 Builds and optionally signs macOS Agent packages.
.github/​workflows/​release.yml Includes both macOS packages in release outputs.
.github/​workflows/​README.md Documents macOS signing and notarization secrets.
.github/​workflows/​package.yml Signs, notarizes, and verifies macOS Agent artifacts.
.github/​workflows/​ci.yml Builds macOS Agent packages and checks arm64 installation.

Review effort: Balanced

Comment thread package/AgentMacOS/scripts/postinstall Resolved
Comment thread package/AgentMacOS/scripts/preinstall Resolved
Use the Microsoft PowerShell install path instead of Homebrew prefixes so a user-writable location cannot supply the root daemon's interpreter. Secure existing configuration directories and wait for launchd to unload before replacing or removing package files.

Security: yes

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Create an existing data directory with a broad ACL so the package smoke test verifies postinstall removes it. Document the symlink and unload timeout paths that the smoke test cannot exercise.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@mamoreau-devolutions
Marc-André Moreau (mamoreau-devolutions) merged commit 86d84a6 into master Nov 12, 2026
106 of 110 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants