Your Mac App Breaks on February 1, 2027 Unless You Re-Sign It
Apple's original Developer ID Sub-CA expires February 1, 2027. How to audit what you signed, what keeps working, and the order to re-issue from G2.
On October 1, 2026, Apple Developer News published “Upcoming expiration of Developer ID Certification Authority (Sub-CA).” If you ship Mac software outside the App Store — a companion app, an internal tool, a Sparkle-updated beta — you have a dated deadline and a small amount of work that gets much more expensive if you leave it until January. Everything below was verified against Apple’s own pages on October 5, 2026.
What actually expires, and what doesn’t
The original Developer ID Certification Authority expires on February 1, 2027 — Apple’s PKI page gives the exact instant as 02/01/2027 22:12:15 UTC. Apple’s wording is blunt: “Certificates issued by this authority will stop working on that date.” The replacement, Developer ID Certification Authority (G2), runs until 2031 (Apple’s PKI page says 09/17/2031 00:00:00 UTC; the support page says September 16, 2031 — the same moment in a different time zone).
Two things die. You can no longer sign with a certificate issued by the old Sub-CA. And, per Apple: “Starting February 1, 2027, .pkg files signed with an affected certificate will no longer install. Re-sign all packages with your new certificate before this date.”
Three things survive. Already-shipped Mac apps that were signed and notarized with a secure timestamp “will keep working—no action needed.” Apps already installed on a user’s machine keep running — Apple’s certificates overview says users can still download, install and run versions signed with an expired Developer ID Application certificate. And your Team ID is unchanged by a re-issue, which is what keeps the second-order damage survivable.
Mac App Store distribution is untouched. Those builds chain through Apple Worldwide Developer Relations Certification Authority – G3, which expires 02/20/2030. iOS is not in scope at all. If someone forwards you the announcement in a panic about an App Store app, that is the one-sentence answer.
There is a real gap in the announcement. Apple’s survival guarantee is explicitly scoped to software that was “previously signed and notarized” with a secure timestamp. Software that was signed but never submitted to the notary service — internal CLI tools, side-loaded helpers, old betas — is not covered by that sentence, and I could not find an Apple statement about it either way. Treat it as an open question, not a prediction. The action is the same regardless: notarize that software now. Apple recommends notarizing everything you’ve distributed, including older releases and unsigned software, and says “you don’t need to rebuild or re-sign your software before submitting it for notarization.” Back-catalogue notarization is cheap.
Audit before you touch the portal
Start with what identities you actually hold. Stale duplicates in a keychain are a documented cause of re-signing silently picking the wrong certificate — Quinn (“The Eskimo!”) raises exactly this in Apple forum thread 699651.
security find-identity -v -p codesigning
security find-identity -v # also lists installer identities
Now determine which Sub-CA issued each certificate. Apple’s documented method: in Keychain Access, select your certificate, expand Issuer Name, and read Organizational Unit. G2 means current, no action. Apple Certification Authority means it came from the expiring Sub-CA.
Two traps here, both documented by Apple. Do not inspect the “Developer ID Certification Authority” entry in your keychain — that one is issued by Apple Root CA and legitimately shows Apple Certification Authority in its OU, which generates a false positive. And “expiration date alone doesn’t prove issuing authority.” Check the issuer, every time.
To audit a shipped artefact rather than a keychain, extract the chain and read the issuer directly. You want OU=G2 in the issuer of the leaf (codesign0; codesign1 is the intermediate):
codesign -d --extract-certificates MyApp.app
openssl x509 -inform der -in codesign0 -noout -subject -issuer -enddate
For installers, pkgutil --check-signature file.pkg tells you whether a trusted timestamp is present and names the signing identity — but it prints the intermediate’s common name, which reads “Developer ID Certification Authority” for both generations. The generation lives in the OU, which pkgutil doesn’t show. So: pkgutil for timestamps, extract-certificates for generation. If non-engineers need to run their own check, Apparency (apps) and Suspicious Package (installers) explain why a signature is or isn’t valid, instead of macOS’s generic “damaged” message.
The one check that matters most: secure timestamps
A secure timestamp turns “is this certificate valid today?” into “was this certificate valid when the software was signed?” Quinn’s phrasing in thread 702219: the trusted timestamp “allows macOS to verify that the Developer ID certificate was valid at the time the installer was signed.”
That gives you the asymmetry worth memorising: expiry is survivable with a timestamp; revocation is not. Revocation asserts the key was never trustworthy, and no timestamp repairs that.
Checking is one command, and Apple documents the exact strings to look for in Resolving common notarization issues: output containing a Timestamp value with a date means a secure timestamp is present; the presence of Signed Time means it isn’t.
codesign -dvv MyApp.app 2>&1 | grep -E 'Timestamp|Signed Time|Authority'
Here is the default that catches people. Apple, verbatim: “By default, Xcode doesn’t include a secure timestamp as part of the app’s code signature during the build process. Instead, it adds a secure timestamp only during the archive (as of Xcode 10.2) and export workflows.” Archive and export timestamp for you. Scripted and CI signing paths do not, unless you ask — which is precisely the population shipping betas and tools from a build script.
codesign --force \
--sign "Developer ID Application: Your Name (TEAMID)" \
--options runtime \
--timestamp \
MyApp.app
One infrastructure note for locked-down build networks: generating a secure timestamp requires internet access, and macOS accepts only one timestamp server, timestamp.apple.com. As documented on 2026-10-05, that covers IPv4 ranges 17.32.213.0/24, 17.157.80.0/24, 17.179.249.0/24 and IPv6 2620:149:980:500::/64, 2620:149:981:603::/64, 2620:149:982:404::/64. Those ranges change; link to Apple’s page rather than hardcoding them in a runbook. pkgbuild, productbuild and productsign include a secure timestamp by default with their sign option — don’t generalise that to codesign.
Order of operations for the re-issue
1. Audit first. Produce an inventory: every shipping artefact, its certificate generation, whether a secure timestamp is present, whether it’s notarized, whether it’s a .pkg.
2. Find out who holds the Account Holder role. Apple requires Account Holder to create Developer ID certificates. That is often not the engineer doing the work, and that scheduling fact — not anything technical — is the usual reason a short task stretches into weeks.
3. Create the new certificates, and watch the intermediary picker. Certificates → + → under Software, Developer ID Application or Developer ID Installer. At the prompt, select “G2 Sub-CA (Xcode 11.4.1 or later)”. Apple’s own warning: “Any other option might issue a certificate from the expiring Certificate Authority.” This is the part worth repeating — Apple has issued from G2 by default since January 27, 2022, but the portal still offers the legacy option, so a certificate created today can still expire on February 1, 2027. If you hold both types, do both: one certificate does not cover the other. You may hold up to five of each concurrently, specifically so you can create and test a replacement while the current one still works.
4. Install the G2 intermediate everywhere you sign, including CI runners and any freshly-imaged Mac. Xcode 13.2 and later fetch it automatically when signing; otherwise take it from apple.com/certificateauthority. Skip this and you get failures in the family of productbuild --sign reporting “unable to build chain to self-signed root.”
5. Do not revoke or delete the old certificate. This is the most dangerous mistake available during this migration. Apple’s certificates overview draws the contrast explicitly: when a Developer ID Application certificate expires, users can still download, install and run software signed with it; when it is revoked, “users will no longer be able to install applications that have been signed with this certificate.” Revocation is retroactive in a way expiry is not. Separately, Apple states the old intermediate “is still required in order to sign content with existing Developer ID signing certificates” — deleting it mid-migration breaks anything still signed with a G1 leaf.
6. Re-sign the installers. You don’t need to rebuild from sources. Quinn, thread 699651: productsign “is capable of completely replacing an installer package’s signature.”
productsign --sign "Developer ID Installer: Your Name (TEAMID)" old.pkg new.pkg
pkgutil --check-signature new.pkg
If identity resolution misbehaves, pass the SHA-1 hash from security find-identity -v instead. The expiry date in the verification output should reflect the new certificate, not the old one.
7. Re-notarize and re-staple anything you re-signed. Re-signing changes the code directory hash, and the existing ticket is keyed to the old cdhash, so stapling fails to find a match. Apple’s guidance is to staple exactly the file you submitted.
8. Budget for notary throughput. Apple documents a ceiling of 75 notarizations per day, with most submissions under 5 minutes and “98 percent of software within 15 minutes.” A long tail of installers is a multi-day calendar item.
9. Test as a user, not as a developer. Download over HTTP so the quarantine attribute is set, then install. One caveat on verification tooling: forum thread 817887 (March 2026) documents a correctly signed, notarized and stapled .pkg that passes pkgutil --check-signature, stapler validate and notarytool info but is rejected by spctl -a -vvv --type install on macOS 26.3. Apple DTS engaged and the thread ends unresolved. Don’t read an spctl --type install rejection as proof your re-sign failed — cross-check with the other tools and a real quarantined download.
What else is keyed to your certificate
This is where the announcement’s three bullet points stop being enough. Anything on macOS that identifies your code by its designated requirement is in scope. Apple DTS, thread 654410: “If the DR changes, that’s considered to be different code… Thus, the system treats them as completely separate programs.” In that thread the consequence was a tool silently losing access to its own keychain items and triggering fresh authorisation prompts.
The standard Developer ID DR pins on the Apple anchor, the signing identifier, Apple’s marker OIDs for the Developer ID Sub-CA and Developer ID Application, and leaf[subject.OU] — your Team ID. It does not reference the certificate serial, the validity window, or the Sub-CA generation. So a same-team G1→G2 re-issue should leave the DR unchanged, and DR-keyed state should survive. That reasoning comes from the DR grammar, not from an Apple statement, so verify it on your own build:
codesign -d -r- MyApp.app # diff a G1-signed build against a G2-signed one
Four things to put on the audit list. Sparkle: its documentation says Sparkle “allows rotating keys by issuing a new update that changes either your Apple code signing certificate or your EdDSA keys (but not both)” — so don’t rotate the Developer ID certificate and the EdDSA key in the same release. Sparkle’s EdDSA signing is independent of Apple’s PKI and unaffected by this event. Privileged helpers registered via SMAppService or SMJobBless match on requirement strings; look for any hand-written requirement that pins something narrower than the Team ID. Keychain ACLs, which is thread 654410’s actual failure. And any signature validation you wrote yourself, which is the real lesson of the January 2026 Logitech breakage: Jeff Johnson argues it was not macOS refusing to run an app with an expired certificate but Logitech’s own validation logic failing — “an unforced error.” His statement of the platform rule is the one to keep: if the certificate was valid when the app was signed, the app keeps running unless Apple revokes the certificate. A home-grown certificate-expiry check is a scheduled outage.
One more expiry mechanism that’s easy to miss: Developer ID provisioning profiles. They’re optional, used for capabilities like CloudKit and push — but if the profile expires, the app no longer launches. Apps that use one have a failure mode that apps without one simply don’t have.
What Apple hasn’t reconciled
Two of Apple’s documented positions are in tension, and it’s worth knowing that rather than being surprised by it. The October 1, 2026 announcement says .pkg files signed with an affected certificate “will no longer install.” But Apple’s certificates overview says that when a Developer ID Installer certificate expires, “users can still install packages that were signed with this certificate as long as the package includes a trusted timestamp” — and Quinn, in thread 702219, confirms the same timestamp logic applies to installers as to apps and notes he filed a bug against an older contradicting article.
An expiring leaf with a valid timestamp is documented as fine. Apple now says an expiring Sub-CA is not, for packages. Apple hasn’t published the mechanism that reconciles those, and the third-party explanations circulating are speculation. The engineering conclusion holds either way: the announcement is the operative instruction, so re-sign the packages. When the authoritative source and the general rule disagree about your specific case, follow the authoritative source and keep the general rule for reasoning about everything else.
There’s also a genuine judgement call on scope. Apple’s instruction is categorical — “re-sign all packages.” Against that, every re-signed package needs re-notarization and re-stapling against a 75/day ceiling, and for artefacts nobody can obtain any more, that’s pure cost; a dead download URL is a cheaper fix than a dead package. The deciding question is simply whether anyone can still get hold of the installer. Old installers do live on in MDM repositories, wikis and support email threads for years.
One change to release engineering that is easy to skim past: G2-issued certificates “expire annually and must be renewed each year” (Apple, October 1, 2026). That’s a recurring annual task, and an annual opportunity to be caught out mid-release. Unrelated, despite surfacing in the same searches: the CA/Browser Forum’s industry-wide code-signing validity reduction is a separate thing and doesn’t apply to the Developer ID program.
Why this is an October job
No cost estimate is needed to make the case. Count the dependencies instead.
The re-issue requires the Account Holder, who may not be you and may be hard to schedule. Secure timestamps require reachability to timestamp.apple.com specifically, which on a locked-down build network means a firewall change in someone else’s queue. Notarization is capped at 75 per day, so a back catalogue is a calendar item. And the five-certificates-of-each-type allowance only helps you before the deadline: right now you can create a G2 certificate, sign a test build, verify the timestamp and the designated requirement, and roll forward in parallel with zero risk to the current release. Once the old certificate is dead, all of that sits on the critical path.
The deadline is 2027-02-01 22:12:15 UTC. It lands a few days after a typical January release window. Four dependencies on other people, none of them compressible — that’s the entire argument.
If you do one thing today, run codesign -dvv across your shipping artefacts and look for Timestamp= rather than Signed Time=. That single distinction separates “already shipped, still fine” from “users start seeing a broken app,” and since macOS 15 Sequoia removed the Control-click Gatekeeper override, the broken case is far more visible than it used to be — users have to go to System Settings → Privacy & Security → “Open Anyway” and authenticate as an admin. “Just right-click to open it” is no longer an answer anyone can give.