Ne soumettez pas une nouvelle fois le même fichier après un échec de notarisation d’une app macOS : commencez par l’état notarytool et son journal, corrigez ensuite le paquet réellement distribué, puis terminez par staple et un test Gatekeeper indépendant. Cette méthode convient si vous distribuez une application hors du Mac App Store avec un certificat Developer ID, sur votre Mac local, dans une CI ou sur un Mac distant.

Vous êtes au bon endroit si vous maintenez une automatisation de signature, de notarisation ou de publication. Le guide couvre aussi les applications contenant des frameworks, des extensions, des modules audio ou vidéo, des outils auxiliaires, un DMG ou un PKG.

La chronologie de décision : arrêter la répétition avant de modifier l’artefact

Un résultat Invalid n’indique pas à lui seul que le certificat est mauvais. Le problème peut se situer dans l’authentification, l’envoi, la signature d’un composant imbriqué, l’empaquetage ou la validation du ticket. À l’inverse, Accepted signifie que le service de notarisation a accepté la soumission ; cela ne prouve pas encore que le fichier téléchargé sera accepté par Gatekeeper.

La première action consiste donc à conserver le contexte exact :

  • l’identifiant de soumission ;
  • la sortie complète de notarytool ;
  • le chemin du fichier envoyé ;
  • le condensat du ZIP, DMG ou PKG final ;
  • la version de Xcode et le chemin sélectionné par xcode-select ou DEVELOPER_DIR ;
  • le type de fichier envoyé et le profil d’identifiants utilisé.

Ne supprimez pas immédiatement un certificat, une clé privée ou un profil d’approvisionnement. Une rotation précipitée peut rendre impossible la comparaison avec le dernier artefact fonctionnel. Exportez d’abord les éléments nécessaires selon votre politique de sécurité, puis prévoyez un retour vers la configuration précédente.

Moment de la chaîne Indice observé Action immédiate Ce qu’il ne faut pas conclure
Authentification ou envoi La commande échoue avant une soumission exploitable Vérifier le profil de trousseau, l’équipe et le fichier local Que le code est mal signé
Traitement de la soumission L’état reste en cours de traitement Conserver l’identifiant et vérifier le service officiel Qu’une attente longue explique toujours un Invalid
Résultat du service Invalid avec un journal disponible Télécharger le journal et traiter la première erreur exploitable Que toutes les erreurs listées ont la même cause
Après acceptation Accepted, mais aucun ticket local ou distribution bloquée Exécuter stapler, validate, puis Gatekeeper Que Accepted équivaut à une publication terminée
Poste utilisateur Alerte Gatekeeper ou installation interrompue Tester le fichier réellement téléchargé sur un Mac indépendant Que l’utilisateur a forcément reçu le fichier testé

Pour comprendre la séparation entre soumission, journal, ticket et contrôle local, appuyez-vous sur la procédure officielle de notarisation d’un logiciel macOS avant distribution.

Première étape : inspecter le produit final plutôt que le projet

Une erreur fréquente consiste à contrôler l’application issue de l’archive Xcode, alors que le fichier envoyé est un ZIP généré par une autre étape, un DMG reconstruit ou un PKG produit par un script différent. La notarisation porte sur l’artefact soumis, pas sur l’intention de votre projet.

Décompressez donc le même ZIP que celui transmis au service. Pour un DMG, montez l’image et inspectez l’application qui s’y trouve. Pour un PKG, examinez le contenu installé ou les composants qu’il embarque, en tenant compte du fait qu’un installateur peut déposer d’autres exécutables.

Une vérification initiale peut suivre cette séquence :

  1. identifiez le binaire principal et les architectures réellement présentes ;
  2. contrôlez la signature avec codesign --display --verbose=4 et codesign --verify --deep --strict --verbose=4 ;
  3. confirmez la présence du runtime renforcé et d’un horodatage sécurisé ;
  4. inspectez les droits avec codesign -d --entitlements :- ;
  5. parcourez les frameworks, plugins, extensions, agents, éléments de connexion et outils auxiliaires ;
  6. vérifiez que le fichier final n’a pas été modifié après sa signature.

La qualification --deep peut aider à inspecter une hiérarchie, mais elle ne doit pas masquer une mauvaise structure de signature. Si un plugin est corrigé après la signature de l’application, la vérification précédente n’est plus valable. Il faut reprendre la chaîne à partir du composant modifié, puis remonter vers l’extérieur.

Élément à contrôler Preuve recherchée Risque si le contrôle est ignoré
Application principale Identité Developer ID, runtime renforcé, horodatage Refus malgré une compilation réussie
Framework ou plugin Signature cohérente avec le composant et son emplacement Journal pointant vers un chemin imbriqué
Entitlements Format valide et droits compatibles avec la distribution Rejet lié à get-task-allow ou à un droit inattendu
Archive exportée Produit identique à celui de la soumission Diagnostic réalisé sur le mauvais fichier
DMG ou PKG Conteneur reconstruit après la signature interne Ticket ou validation attaché au mauvais artefact

Pour les différences entre Archive, Export et paquet de distribution, consultez la documentation Apple consacrée à l’empaquetage d’un logiciel Mac pour la distribution. Cette distinction est particulièrement importante pour les applications créatives qui livrent en plus des banques audio, des extensions vidéo, des modules de design ou des outils de conversion.

Une application macOS signée peut-elle tout de même échouer à la notarisation ? Oui. La signature prouve une relation entre un certificat et du code à un moment donné, mais elle ne garantit pas que chaque composant imbriqué, entitlement, horodatage ou conteneur respecte les exigences de la distribution. Une application peut donc être signée et échouer lorsque le service examine le produit complet.

Deuxième étape : laisser le premier message exploitable guider la correction

Lorsque notarytool renvoie Invalid, récupérez d’abord les informations liées à l’identifiant de soumission, puis téléchargez le journal détaillé. Le principe est de partir du premier message qui désigne un chemin, un composant ou une propriété précise, plutôt que de corriger plusieurs variables à la fois.

La forme exacte des commandes dépend de votre méthode d’authentification, mais la logique reste la même :

xcrun notarytool info IDENTIFIANT_REDACTED \
  --keychain-profile PROFIL_REDACTE

xcrun notarytool log IDENTIFIANT_REDACTED \
  --keychain-profile PROFIL_REDACTE \
  journal.json

Ne publiez jamais dans un ticket ou un dépôt le nom réel de l’équipe, l’identifiant Apple, le nom du certificat, le profil de trousseau, le chemin privé ou l’hôte. Remplacez ces valeurs par des libellés neutres dans les exemples et conservez le journal original dans un stockage d’incidents à accès restreint.

Voici une grille de lecture opérationnelle :

  • Signature invalide ou code modifié : comparez le condensat et le fichier réellement envoyé, puis inspectez le composant indiqué par le chemin du journal.
  • Horodatage sécurisé absent : reprenez la signature avec la configuration de distribution appropriée ; ne vous contentez pas de déplacer le fichier dans un nouveau ZIP.
  • get-task-allow présent : vérifiez que vous n’avez pas envoyé un produit de développement ou une exportation destinée au débogage.
  • Entitlements incorrects : comparez les droits demandés par l’application avec ceux effectivement présents dans le binaire signé.
  • Mauvais type de certificat : confirmez que la distribution hors Mac App Store utilise l’identité Developer ID adaptée, et non une identité réservée à un autre canal.
  • Composant imbriqué oublié : recherchez les frameworks, plugins, extensions ou outils auxiliaires que le script de signature n’a pas parcourus.

La page Apple sur les problèmes courants de notarisation et leur résolution sert de référence pour relier le message du journal à la correction autorisée. Elle doit rester prioritaire sur les recettes copiées depuis un forum, surtout lorsqu’un comportement dépend de la version de Xcode ou de l’outil utilisé.

Comment consulter l’erreur précise après Invalid ? Utilisez l’identifiant de soumission avec les commandes info et log, puis ouvrez le journal JSON obtenu. Traitez d’abord l’erreur qui pointe vers un fichier ou une propriété concrète ; ne relancez pas une soumission identique avant d’avoir modifié et vérifié l’artefact concerné.

Troisième étape : signer de l’intérieur vers l’extérieur

Une fois la cause établie, corrigez le composant le plus profond. Pour une application qui contient un plugin ou un framework, la séquence fiable est généralement :

  1. remplacer ou corriger le composant imbriqué ;
  2. signer ce composant avec l’identité de distribution retenue ;
  3. signer les niveaux intermédiaires qui le contiennent ;
  4. signer l’application principale ;
  5. vérifier la hiérarchie complète ;
  6. créer le conteneur final ;
  7. soumettre uniquement ce nouveau conteneur.

Cette direction évite de produire une application dont la signature extérieure semble correcte alors qu’un module interne reste ancien ou modifié. Elle est essentielle pour les outils audio avec extensions, les applications vidéo qui chargent des codecs, les logiciels de design dotés de plugins et les utilitaires qui embarquent un agent séparé.

Ne modifiez plus le contenu du bundle après la signature finale. Une opération apparemment anodine — remplacement d’une ressource, ajout d’un fichier de configuration ou reconstruction du DMG — peut rendre inutiles les contrôles précédents.

Le ZIP, le DMG et le PKG ne se traitent pas exactement de la même manière :

  • le ZIP sert souvent à transmettre l’application dans une enveloppe conservant sa structure ;
  • le DMG ajoute une image disque et une présentation de distribution, mais l’application qu’il contient doit déjà être correctement signée ;
  • le PKG est un installateur qui peut déposer plusieurs éléments, dont certains exécutables, et demande donc une vérification de son contenu et de son flux d’installation.

Consultez le guide Apple sur la personnalisation du flux de notarisation avant de transformer un script de correction en procédure automatique. Si le PKG installe du code exécutable supplémentaire, analysez le flux complet au lieu de supposer que la validation du conteneur couvre toutes les opérations effectuées à l’installation.

Quelle branche choisir avant de relancer ?

Utilisez les conditions suivantes pour éviter une nouvelle soumission aveugle :

  • Si le journal cite un chemin précis, corrigez d’abord ce composant, puis recommencez la signature de l’intérieur vers l’extérieur.
  • Si l’erreur concerne l’identité ou les entitlements, arrêtez la publication et comparez l’environnement de signature avec le dernier artefact connu.
  • Si l’envoi échoue avant la création d’un identifiant exploitable, vérifiez l’authentification et le fichier local sans modifier le bundle.
  • Si la soumission est acceptée mais que le contrôle local échoue, ne renvoyez pas immédiatement le fichier : passez à stapler, validate et Gatekeeper.
  • Si le résultat reste en traitement sans erreur détaillée, conservez l’identifiant, contrôlez l’état officiel du service et définissez une limite d’attente avant toute nouvelle tentative.
  • Si le fichier a été modifié après signature, revenez à l’étape de signature, même si une vérification antérieure était positive.

Apple indique dans sa note technique sur la migration vers l’outil de notarisation actuel que notarytool est le flux en ligne de commande à utiliser. L’ancien altool n’est plus accepté par le service de notarisation depuis le 1er novembre 2023 ; ne construisez donc pas un nouveau pipeline autour d’une ancienne commande.

Quatrième étape : distinguer Accepted de la publication réellement vérifiée

Après une acceptation, récupérez le résultat sur le même artefact et appliquez le ticket lorsque le format le permet. Une séquence typique utilise stapler pour attacher ou vérifier le ticket, puis une validation locale :

xcrun stapler staple APPLICATION.app
xcrun stapler validate APPLICATION.app
spctl --assess --type execute --verbose=4 APPLICATION.app

Adaptez la cible au format réellement distribué. Ne testez pas uniquement le dossier de travail si vos utilisateurs téléchargent un DMG ou un PKG. Montez l’image ou installez le paquet dans un environnement de test, puis contrôlez le fichier qui sort véritablement du processus de publication.

Faut-il encore exécuter stapler après Accepted ? Oui, lorsque votre flux de distribution doit embarquer le ticket dans le produit ou lorsque vous voulez vérifier explicitement cette étape. Accepted confirme l’issue de la soumission côté service ; stapler validate, Gatekeeper et une installation indépendante vérifient ensuite la chaîne telle qu’elle sera rencontrée par l’utilisateur.

Effectuez au moins trois contrôles distincts :

  • une validation sur le Mac de publication ;
  • une installation hors ligne ou avec réseau limité, afin de ne pas dépendre uniquement d’une récupération en ligne ;
  • un test sur un Mac qui ne possède ni les caches de développement ni les fichiers temporaires de votre équipe.

Conservez le condensat du fichier testé et comparez-le avec celui envoyé. Cette précaution élimine un défaut banal : l’équipe valide l’artefact accepté, mais publie ensuite une nouvelle archive créée par un script différent.

Cinquième étape : transformer la correction en chaîne reproductible sur un Mac distant

Un Mac distant est pertinent lorsque votre poste de développement ne peut pas conserver en permanence la clé privée Developer ID, le bon environnement Xcode et les journaux de publication. Il ne corrige toutefois pas une mauvaise procédure : il peut au contraire rendre les dérives plus difficiles à repérer si plusieurs sessions et plusieurs versions d’outils sont utilisées.

Commencez par figer le chemin de développement avec xcode-select ou DEVELOPER_DIR. Enregistrez avec chaque artefact la version de Xcode, l’identité de signature utilisée, le profil d’identifiants, le condensat du paquet et l’identifiant de soumission. Séparez les secrets des journaux ; un journal utile ne doit pas contenir de mot de passe ni de clé privée.

Une automatisation robuste doit aussi prévoir :

  • un délai maximal pour l’attente du résultat ;
  • une distinction entre erreur d’authentification, Invalid, indisponibilité temporaire et acceptation ;
  • un nombre limité de nouvelles tentatives ;
  • un arrêt humain avant toute suppression de certificat ou rotation de clé ;
  • la conservation du journal JSON et de la sortie de stapler ;
  • une reprise après déconnexion SSH ou redémarrage ;
  • une vérification graphique lorsque le flux comprend une session utilisateur, un trousseau ou une validation Gatekeeper.

Pourquoi une notarisation réussie localement peut-elle échouer sur un Mac distant ? Les causes les plus fréquentes sont une autre sélection de Xcode, un profil de trousseau absent, une clé privée non accessible dans la session active, un fichier différent ou une étape de packaging exécutée avec des variables différentes. Comparez d’abord le contexte et le condensat ; ne remplacez pas les identifiants au hasard.

Vous pouvez réserver une machine persistante à cette chaîne, avec des permissions limitées et une procédure de reconstruction documentée. Si vous devez déplacer les certificats et les clés privées, testez d’abord une version non officielle, vérifiez la signature, puis exécutez une soumission complète avant de retirer l’ancien environnement.

Pour une équipe qui ne souhaite pas acheter une machine dédiée uniquement à la publication, VMSPIN permet d’étudier un environnement Mac distant adapté à un flux de signature et de validation. La décision doit rester technique : vous devez pouvoir contrôler les accès, conserver les journaux et reproduire le même chemin d’outils.

Le choix final : poste local, CI ou Mac distant ?

La bonne solution dépend moins du volume de code que de la stabilité requise autour de la clé privée et du processus de publication.

  • Choisissez le poste local si une seule personne publie ponctuellement, possède déjà un environnement stable et peut refaire manuellement les contrôles.
  • Choisissez une CI si les secrets, les journaux et le choix de l’outil sont correctement isolés, avec une procédure de récupération après échec.
  • Choisissez un Mac distant persistant si vous devez conserver une chaîne macOS dédiée, exécuter des publications régulières, tester une application audio ou vidéo volumineuse, ou séparer le poste de création du poste de distribution.
  • Restez sur une machine physique contrôlée si vous avez besoin d’interfaces matérielles, de périphériques spécialisés ou d’un traitement lourd et permanent qui rend la location moins pertinente.

Un poste de développement instable entraîne des échecs difficiles à comparer : clés absentes, sessions graphiques interrompues, chemins Xcode variables, DMG reconstruits sur une autre machine et journaux dispersés. Dans ce cas, la location d’un Mac apporte surtout une base persistante et contrôlable ; elle ne remplace pas la discipline de versionnement des scripts.

Si votre objectif est de déplacer la signature et la notarisation vers une machine isolée, examinez les formules Mac de VMSPIN après avoir reproduit le flux avec une version non officielle. Pour un usage ponctuel de publication, cette approche peut éviter l’achat d’un Mac dédié ; pour une charge constante nécessitant des accès matériels locaux, un achat reste parfois plus cohérent.

Pour votre prochaine version, conservez donc une chronologie complète : Build, Archive, Export, Sign, Package, Submit, Accepted, Staple, puis Gatekeeper. Si votre solution actuelle mélange ces étapes, utilise plusieurs chemins Xcode et perd les journaux après une déconnexion, elle vous oblige à diagnostiquer à l’aveugle et à conserver une machine de développement mobilisée en permanence. Un Mac distant réservé à la publication offre alors une séparation plus propre entre création, signature et validation, à condition de tester d’abord la chaîne complète sur une version non officielle et de maintenir une procédure de retour.