The short answer
No publicly trusted code signing certificate will get a Mac app past Gatekeeper, whatever the certificate authority sells it as. macOS accepts one signing hierarchy for distributed software, and Apple is the only issuer inside it: you need an Apple Developer Program membership, a Developer ID Application certificate, and a separate notarization step that Apple has required for software distributed outside the Mac App Store since macOS 10.15 Catalina. A commercial code signing certificate remains the right tool for everything Apple does not control, Windows executables, installers, drivers, PowerShell, Java, and it signs those perfectly well from a Mac. Teams shipping one desktop app to both platforms need both certificates, and that is the part most people find out late.
On this page
- Does a code signing certificate work on macOS?
- Two signing systems that never meet
- What Apple requires: Developer ID and notarization
- What Gatekeeper checks before an app opens
- What your CA certificate still signs
- Shipping the same app to Windows and macOS
- Four asymmetries that catch teams out
- Internal distribution: the narrow exception
- Which certificate do you actually need?
- FAQ
Does a code signing certificate work on macOS?
It works in the narrow sense that the signature applies and verifies cryptographically. It does not work in the sense you care about: macOS will still refuse to open the app. Gatekeeper does not ask whether a signature is valid in general. It asks whether the signing identity chains to Apple's own Developer ID certificate authority, and a commercial CA cannot issue into that hierarchy.
This trips people up because the failure is silent at the point where you would expect an error. Run codesign against an identity in your keychain and it will happily sign the bundle. Run codesign --verify and the signature checks out. Copy the app to a colleague's Mac, and the block dialog appears with no mention of certificates at all.
The mismatch usually comes from how code signing is sold. A certificate authority sells one product called a code signing certificate, so it reads like a general-purpose credential for signing software. In practice it is an Authenticode credential, and Authenticode is Microsoft's format. Apple built something separate, closed it, and never opened it to third-party authorities.
Two signing systems that never meet
Windows and macOS both check who signed a program before running it, and they answer that question through entirely separate trust stores. Windows validates Authenticode signatures against the public CA roots in its own program, which is why any publicly trusted CA can serve you. macOS validates against Apple's Developer ID chain, which contains exactly one issuer.
| What you are signing | Signature format | Who has to issue the certificate |
|---|---|---|
| EXE, DLL, MSI, MSIX, CAB | Authenticode | Any publicly trusted CA |
| .app bundle, .dmg, .pkg | Apple code signature, plus a notarization ticket | Apple, through the Developer Program |
| JAR, JNLP | PKCS #7 via jarsigner | Any publicly trusted CA |
| PowerShell, VBA, ClickOnce manifests | Authenticode | Any publicly trusted CA |
| Kernel-mode Windows drivers | Authenticode, then Microsoft attestation | EV certificate from a publicly trusted CA |
Read down the third column and one row stands apart. Everything else in the table is served by the same certificate you would buy for Windows work. The Apple row is the exception, and it is the only row where money spent with a CA buys you nothing.
What Apple requires: Developer ID and notarization
Distributing a Mac app from your own website takes three things: an Apple Developer Program membership, a Developer ID Application certificate created inside that account, and a notarization pass on each build you ship. Membership costs 99 USD per year. The certificate is free once you are a member. Notarization is free and automated, and it is not optional.
Four details from Apple's own documentation are worth pinning to the wall before your first release:
- Only the Account Holder can create one. Inside an organisation account, no other role can generate a Developer ID certificate. If that person has left the company, sorting it out with Apple takes longer than any release window you have.
- You get five of each. Apple allows up to five Developer ID Application and five Developer ID Installer certificates per account. Machines get replaced and certificates get orphaned, so the limit arrives sooner than teams expect.
- They last five years. Long enough that nobody remembers the renewal, which is an argument for putting the expiry date somewhere a person will actually look.
- Application and Installer are different certificates. One signs the app bundle, the other signs a .pkg installer that wraps it. Shipping a .pkg means you need both.
Notarization is the step people underestimate. Apple has required it for new software distributed outside the Mac App Store since macOS 10.15 Catalina, and it is a separate submission: you upload the signed build, Apple scans it, and you staple the resulting ticket to the artifact so Gatekeeper can find it offline. A build that is signed correctly but never notarized is blocked exactly like an unsigned one.
Notarization also has prerequisites of its own. The hardened runtime has to be enabled, and every nested binary needs a valid signature. Cross-platform frameworks tend to bundle helper executables that get missed on the first attempt, which is why the first notarization of any Electron or Tauri project reliably fails at least once.
What Gatekeeper checks before an app opens
Gatekeeper runs four checks on a downloaded application, in order: is it signed, does the signature chain to Apple's Developer ID authority, has Apple notarized this exact build, and do the files on disk still match what was signed. Failing any one of them produces a block. A third-party certificate fails the second check, which is the one no amount of configuration can fix.
Users can still override a block, but Apple has been steadily making that harder. As of macOS Sequoia the old shortcut of right-clicking an app and choosing Open no longer works on a first launch; the override moved into System Settings under Privacy and Security, behind an admin password. That is fine for a developer testing a build and close to fatal for a product you are asking strangers to install.
One useful diagnostic: spctl -a -vvv -t install against your app tells you what Gatekeeper thinks of it without needing a second machine. A rejection reading source=no usable signature is a different problem from one reading source=Unnotarized Developer ID, and the fix differs accordingly.
What your CA certificate still signs
A publicly trusted code signing certificate covers everything Apple does not gatekeep, which is most of what a desktop team ships. Windows executables, DLLs, MSI and MSIX installers, CAB files, PowerShell scripts, Office VBA projects, ClickOnce manifests, Java archives and NuGet packages all take a signature from the same certificate. Kernel-mode drivers need the EV tier on top.
None of that requires a Windows machine. Both osslsigncode and Jsign apply Authenticode signatures from macOS, reaching a USB token or a cloud signing service over PKCS #11. A Mac-based build agent can therefore produce signed, timestamped Windows binaries without a Windows VM anywhere in the pipeline. The walkthrough in signing a Windows EXE on Linux or macOS covers the exact commands.
So the certificate is not wasted on a Mac-centric team. It simply does a different job from the one people assume when they buy it. If you are working out which tier that job needs, the OV and EV code signing certificates we sell differ mainly in what identity gets validated and whether kernel-mode driver signing is on the table.
Timestamping matters more here than on the Apple side. An Authenticode signature carrying an RFC 3161 timestamp stays valid after the certificate expires, which is the only thing standing between a 460-day certificate and a support queue full of users whose installer stopped being trusted. Our note on why timestamping is not optional goes through the mechanics.
Shipping the same app to Windows and macOS
A cross-platform desktop app needs two signing identities and two signing steps, because the Windows artifact and the macOS artifact are validated by different systems that share nothing. Electron, Tauri, Qt and Flutter desktop projects all land here. Budget for an Apple Developer Program membership and a code signing certificate, not one or the other.
In practice the release pipeline forks after the build:
- macOS branch. Sign the .app with the Developer ID Application identity, enable the hardened runtime, submit to notarization, wait for the ticket, staple it, then package the .dmg or .pkg.
- Windows branch. Sign the .exe or installer with the code signing certificate through the hardware token or cloud service, add an RFC 3161 timestamp, then verify.
- Shared. Neither signature is retroactive. Any post-signing step that rewrites bytes, a repack, a compression pass, an installer that patches a config file, invalidates the signature, so signing goes last on both branches.
The renewal calendars diverge too, and unhelpfully. Apple gives you five years; a code signing certificate issued on or after 1 March 2026 gives you 460 days. One will expire roughly four times during the life of the other, so keeping both dates in the same place is worth the five minutes it takes.
Four asymmetries that catch teams out
The two systems differ most in the places nobody compares before buying: where the private key is allowed to live, how long the certificate lasts, what identity end users see, and what happens when a certificate is revoked. Each of these changes how a release pipeline has to be built, and none of them is obvious from a product page.
- Key storage. Apple lets a Developer ID key sit in the login keychain and be exported as a .p12, which is why every CI guide tells you to base64 a certificate file into a secret. Publicly trusted code signing keys have not been allowed to work that way since 1 June 2023: the CA/Browser Forum requires generation and storage in hardware meeting FIPS 140-2 Level 2 or Common Criteria EAL 4+, and the key is non-exportable. Your Windows signing step needs a token or a cloud HSM; your macOS signing step needs a file. Our comparison of cloud signing versus a USB token is the decision that follows from this.
- Validity. Five years against 460 days, as above. The shorter figure comes from CA/Browser Forum ballot CSC-31 and applies to certificates issued on or after 1 March 2026; the background is in our note on the 460-day code signing validity limit.
- Displayed identity. A Developer ID signature carries your Apple Developer Program account name, which for a solo developer is usually a personal name unless you enrolled as an organisation. A CA certificate carries the organisation name the CA validated. Two different vetting processes, two different names, one product, and users comparing them will notice.
- Revocation. Apple can revoke a Developer ID certificate and push that decision to every Mac, which stops affected apps from launching. A revoked Authenticode certificate behaves differently: correctly timestamped signatures made before the revocation date generally keep validating. The blast radius of a compromised key is not the same on both sides.
Internal distribution: the narrow exception
Inside a managed fleet, a Mac can be told to trust a certificate it would otherwise reject. An organisation running MDM can deploy its own trust settings and Gatekeeper policy to enrolled devices, which is how internal tools built by an IT team get distributed without an Apple Developer account. This route ends at the boundary of the fleet.
It is worth being precise about what that does and does not buy you. It works on devices you control and nowhere else. A customer downloading your app from the internet is not in your MDM, so nothing you configure reaches them. Treating internal distribution as a preview of public distribution is a good way to discover the difference on launch day.
The same caveat applies to the advice that circulates about self-signed identities and spctl --master-disable. Those are development conveniences. They tell you nothing about how a stranger's Mac will treat your build, and Apple has narrowed each of them over successive releases.
Which certificate do you actually need?
Answer one question and the rest follows: what artifact are you handing to users? A .app or .dmg means Apple, with no CA involved. An .exe, .msi, driver or script means a publicly trusted code signing certificate, regardless of the machine you build on. Both artifacts means both certificates. The operating system you develop on has no bearing on the answer.
One more thing worth settling early, because it is awkward to change later: if you enrol with Apple as an individual rather than an organisation, your personal name is what users see on the signature. Organisation enrolment needs a D-U-N-S number and takes longer, so start it before you need it rather than in the week of a launch.
Frequently asked questions
Sorting out the Windows half
The Apple side of a cross-platform release is a membership and a workflow; the Windows side is a certificate decision, and it is the one with tiers, validation steps and a hardware requirement attached. If you are working out whether OV covers what you ship or whether the EV tier is warranted, our code signing certificate options set out what each tier validates, and cloud signing is available if a USB token would not survive contact with your CI pipeline.
Related reading
- Code signing an Electron app: the two-branch release pipeline in this article, written out as configuration.
- Signing a Windows EXE on Linux or macOS: osslsigncode with a hardware token, command by command.
- Code signing certificates explained: the cluster parent: what OV and EV validate, and what changed recently.