Documentation

Updates

How ProRDP checks for, verifies, and installs new versions, and how its signing keeps a tampered build or CI pipeline from reaching your Mac.

ProRDP checks for new versions once a day and tells you when one is available. It never installs anything until you press Install and Relaunch.

Checking for updates

You’ll see an available update in two places: Settings › General › Software Update, and a line at the top of the menu bar menu.

SettingDefaultDescription
Check for updates automaticallyOnChecks once a day, and again whenever you change the channel. Check Now works either way.
Update channelStableShown only while automatic checking is on. Beta also offers prereleases, such as v1.3.0-beta.1.

If you’re running a beta, you’re still offered the finished release it turns into, even on Stable, because 1.0.0 is newer than 1.0.0-beta.2.

Installing an update

Install and Relaunch downloads the update, verifies it, replaces the app in place, and relaunches.

  • If the server was running, it comes back running after the relaunch, even if Start the server when ProRDP launches is off. If you update over RDP, you won’t lock yourself out.
  • If a client is connected, ProRDP asks before ending its session.
  • Your permissions carry over. macOS ties Screen Recording and Accessibility to ProRDP’s Developer ID, which doesn’t change between versions, so you won’t be asked to grant them again.

Some copies can’t replace themselves. In that case Settings shows a Download button instead of Install and Relaunch, with a note explaining why:

  • ProRDP is still running from the disk image or the Downloads folder. Move it to Applications first.
  • ProRDP is in a folder your user account can’t write to.
  • The copy is a local or development build that isn’t signed with ProRDP’s Developer ID.

Privacy

The update check only contacts api.github.com and github.com, for the prordp-app/release repository. Requests carry a ProRDP/<version> user agent and nothing else about your Mac.

How updates are signed

An update has to pass two independent signatures before ProRDP installs it. Neither one is held by GitHub or the build pipeline alone, so compromising the build system, the release repository, or the network isn’t enough to put a binary on your Mac.

  1. The update signature. Each release includes a small manifest naming the disk image, its size, and its SHA-256 hash. The manifest is signed with a private key that is carried only by the release manager. It has never been stored in GitHub or given to CI. Every copy of ProRDP has the matching public key built in.
  2. The Developer ID signature and notarization. The app inside the disk image must be signed by the same Apple developer team and carry the same bundle identifier as the copy you have installed, and Apple must have notarized it.

Separating the build from the signing

Releases are built and notarized by GitHub Actions, but CI never signs the update manifest. Once a build finishes, the release manager downloads the disk image, verifies its Developer ID signature, notarization, team, bundle identifier, and version, and only then signs the manifest locally.

This means a compromised CI run can produce a disk image, but it can’t produce a manifest any copy of ProRDP will accept. And someone holding only the update key still can’t ship a build that wasn’t signed with ProRDP’s Developer ID and notarized by Apple.

The pipeline also checks itself:

  • Before cutting a release. The workflow that publishes a release to prordp-app/release verifies the manifest’s signature against the disk image first. If they don’t match, the release is aborted.
  • Every day. A scheduled job re-verifies every published release. If a file on the release repository changes after the fact, the check fails and the maintainer is alerted. Installed copies refuse the altered update in the meantime.

What ProRDP checks before installing

CheckProtects against
The manifest’s signature verifies against a key built into your copy of ProRDPA tampered release repository, a man-in-the-middle on the network, or a compromised CI run
The signed version matches the release, and is newer than what you haveBeing rolled back to an older, vulnerable release
The signed version is allowed on your chosen channelA beta reaching Stable users by mistake
The disk image’s size and SHA-256 match the signed manifest, before it’s mountedA swapped download, or a malicious disk image reaching macOS’s disk image tools
The app copied out of the image passes a strict code-signature check against your installed copy’s Developer ID, and is notarizedA build that wasn’t signed by ProRDP’s developer, even if the update key leaked
The copied app’s version matches the signed versionA genuine but different ProRDP build placed in the image

The app that’s checked is the exact copy that gets installed, so nothing can be swapped in between the check and the install. GitHub’s release title, tag, and prerelease flag only decide what to download; what gets installed is decided by the signed manifest alone.

Limits

No update system is 100% perfect and impossible to bypass (although we’ve done a lot to make it very, very hard). An attacker would need both the update key and ProRDP’s Developer ID certificate to ship a malicious update. These values are kept apart deliberately, so that compromising one does not automatically compromise the other. Someone controlling the release repository could also stop you hearing about a new version, but couldn’t change what you install. The daily check is there to catch that.

If an update ever fails verification, ProRDP refuses it and leaves your current version in place.

If you’d still prefer to update manually, you can always disable automatic updates and download and install the latest release by hand.