Note dal lavoro · Apple
Distribuire un’app macOS fuori dall’App Store: firma, notarizzazione e Sparkle
Un’app per Mac non deve per forza passare dall’App Store. Si può distribuire da un sito, come un file DMG, ma bisogna superare Gatekeeper, il controllo che macOS fa su ciò che scarichi. Questa nota riassume il percorso, e come l’ho applicato a Plink, il mio gestore degli appunti per macOS.
1. Firmare l’app
Per distribuire fuori dall’App Store serve un certificato Developer ID Application, che si ottiene con l’iscrizione al programma sviluppatori Apple. L’app va firmata con quel certificato e con l’opzione Hardened Runtime attiva, che limita ciò che il processo può fare (esecuzione di codice generato, caricamento di librerie non firmate) salvo permessi dichiarati.
Il punto delicato è l’ordine: tutto ciò che sta dentro l’app (framework, helper, eseguibili) va firmato prima del pacchetto che lo contiene.
2. Notarizzare
La notarizzazione invia l’app (o il DMG) ai server di Apple, che la analizzano alla ricerca di codice dannoso e controllano la firma. Si fa da riga di comando:
xcrun notarytool submit Plink.dmg --keychain-profile "notary" --wait
Se l’esito è positivo, si applica il ticket al file con xcrun stapler staple (in inglese «stapling», cioè «graffettare»), così Gatekeeper può verificarlo anche senza connessione. Per controllare il risultato prima di pubblicare, spctl --assess --verbose dice se il sistema accetterebbe l’app.
3. Creare il DMG
Il DMG è il formato più comune per distribuire app Mac: si apre, si trascina l’app in Applicazioni e basta. Anche il DMG si firma e si notarizza, e conviene applicare il ticket anche al DMG finale.
4. Aggiornamenti automatici con Sparkle
Senza App Store, gli aggiornamenti li gestisci tu. Sparkle è la libreria più usata per farlo: l’app controlla un file appcast.xml, un elenco delle versioni con indirizzo di download, firma e requisiti, e se trova una versione più nuova propone l’aggiornamento.
- Le release sono firmate con una chiave EdDSA: la chiave pubblica sta nell’app, quella privata resta con te (Sparkle la genera e la conserva nel Portachiavi).
- L’appcast indica anche la versione minima di macOS richiesta.
- Lo strumento
generate_appcastpuò creare anche aggiornamenti «delta», cioè solo le differenze tra due versioni, più piccoli da scaricare. - Basta un hosting statico: l’appcast e i file stanno in una cartella servita via HTTPS.
Come l’ho fatto su Plink
Plink segue questo schema: è distribuito come DMG, firmato e notarizzato, e si aggiorna con Sparkle. L’appcast.xml è servito da GitLab Pages, indica macOS 26 come versione minima e, oltre al DMG completo, pubblica file delta per le versioni precedenti.
Cosa controllare prima di ogni release
- Numero di versione e numero di build aumentati.
- App firmata con Hardened Runtime e notarizzata senza avvisi.
- DMG aperto su un Mac pulito, senza strumenti di sviluppo, per verificare che Gatekeeper non protesti.
- Appcast aggiornato e aggiornamento provato partendo dalla versione precedente.
Il risultato è un’app che si scarica, si apre senza avvisi e si tiene aggiornata da sola, senza dipendere da uno store.