10 points par GN⁺ 2025-12-09 | 1 commentaires | Partager sur WhatsApp
  • Les applications macOS possèdent des composants plus complexes que les programmes en ligne de commande, avec des ressources d’interface comme les fenêtres et les menus gérées dans une structure distincte
  • Sous Classic Mac OS, le code exécutable et les ressources étaient stockés dans le resource fork du fichier, mais à partir de Mac OS X, cela a été remplacé par une structure en bundle
  • Un bundle d’app est organisé autour du répertoire Contents, avec des sous-dossiers comme MacOS, Resources, Frameworks et des fichiers clés comme Info.plist
  • Par la suite, la signature de code, les reçus App Store et la notarisation ont été ajoutés, faisant évoluer cette structure pour renforcer la sécurité et l’intégrité
  • Cette structure autonome de bundle d’application est devenue une base essentielle pour simplifier l’installation, la mise à jour et la suppression, tout en améliorant la sécurité et l’efficacité de maintenance

Structure des apps dans Classic Mac OS

  • Dans les premières versions de Mac OS, les ressources d’interface comme les fenêtres et les menus étaient séparées de l’exécutable et stockées dans le resource fork
    • Par exemple, les ressources de QuarkXPress 4.11 apparaissent dans ResEdit
    • Le code exécutable est contenu dans les ressources CODE, et les informations de type et de creator du fichier y sont également stockées pour que le Finder puisse l’identifier

Structure en bundle dans Mac OS X

  • Mac OS X a introduit la structure en bundle héritée de NeXTSTEP
    • Une app prend la forme d’un répertoire avec l’extension .app, contenant un dossier Contents
    • Le dossier MacOS contient l’exécutable de l’app graphique ainsi que les outils en ligne de commande
    • Le dossier Resources stocke les fichiers de ressources tels que l’icône de l’app et les composants de l’interface graphique
    • Certaines apps incluent un dossier Frameworks pour embarquer des dylib (bibliothèques dynamiques)
  • Le fichier Info.plist est obligatoire et définit le nom de l’exécutable, l’icône, la version minimale de macOS, les types de documents, le numéro de version, etc.
  • Le fichier PkgInfo conserve les informations de type et de creator héritées de Classic Mac OS, mais n’est pas obligatoire
  • Lors du lancement d’une app, launchd démarre le code exécutable, tandis que LaunchServices et RunningBoard effectuent la procédure d’initialisation à partir des informations de Info.plist

Sécurité et extensions dans macOS

  • À partir de Mac OS X 10.5 Leopard (2007), la signature de code a été introduite, avec l’ajout du dossier _CodeSignature
    • Le fichier CodeResources contient le hash du répertoire de code (CDHash) pour vérifier l’intégrité de l’app
  • Les apps distribuées via l’App Store incluent un reçu du Store dans le dossier _MASReceipt
  • Depuis 2018, la notarisation a été introduite, permettant à Apple d’émettre un ticket pouvant être « staple » au bundle via le fichier CodeResources
  • Les bundles d’app modernes intègrent eux-mêmes des composants qui, autrefois, étaient installés dans des dossiers système
    • Dossier Library : LaunchDaemons, LoginItems, etc.
    • Dossier XPCServices : services exécutables séparés utilisés par l’app
    • Dossiers Plugins / Extensions : fonctionnalités d’extension de l’app et App Intents
    • Certaines apps contiennent également un fichier version.plist

Avantages du bundle d’application

  • Le fait de regrouper tous les composants dans le bundle simplifie l’installation, la mise à jour et la suppression
  • Le risque d’absence de composants diminue, et la sécurité est renforcée grâce à la protection par signature et notarisation
  • Les apps App Store ajoutent en plus des reçus et des tickets de notarisation pour renforcer la confiance
  • Il n’existe pas de différence structurelle entre les architectures Intel et Arm : l’exécutable Mach-O est stocké sous forme de binaire universel (fat binary) contenant le code pour les deux plateformes
    • Les signatures propres à chaque architecture sont également présentes dans le même fichier

Vue d’ensemble visuelle de la structure d’une app

  • Dans le diagramme, le jaune pâle désigne les composants obligatoires ou présents dans presque toutes les apps
  • Le vert désigne les éléments présents uniquement dans les apps distribuées via l’App Store, et le bleu correspond au ticket de notarisation optionnel
  • Des éléments supplémentaires comme des workflows Automator ou des scripts peuvent aussi être inclus
  • Dans l’ensemble, les apps macOS ont évolué vers une structure autonome centrée sur la sécurité

1 commentaires

 
GN⁺ 2025-12-09
Commentaire Hacker News
  • La partie en bleu est le notarisation ticket (ticket de notarisation), et en pratique ce n’est pas vraiment optionnel
    Une app non notarisée est tellement pénible à utiliser côté utilisateur qu’au final il faut payer les 99 $ annuels de frais d’inscription développeur Apple
    Si c’est juste pour compiler et lancer pour soi-même, ça passe, mais pour une distribution, macOS affiche une alerte qui donne l’impression que l’app est cassée
    Avant, on pouvait l’exécuter via clic droit, mais maintenant il faut aller jusque dans les Réglages Système pour l’autoriser
    On peut voir des captures d’écran associées dans la documentation d’assistance Apple et dans les actualités développeur
    J’aime la philosophie de sécurité d’Apple, mais je pense que le système de notarisation des apps hors App Store est perdant pour toutes les parties
    Je n’ai pas trouvé de cas concret où la notarisation a réellement empêché un problème de sécurité

    • Je trouvais la notarisation macOS pénible, puis j’ai essayé la distribution sur Windows, et c’était encore pire
      Pour obtenir la confiance de Windows Defender, il faut acheter un certificat, et entreprises comme particuliers doivent passer par une vérification d’identité poussée
      Il faut signer avec un jeton matériel, donc une seule personne peut publier une release
      En plus, l’autorité de certification peut verrouiller la clé de façon arbitraire, donc si ça arrive au moment de publier un correctif de sécurité, c’est catastrophique
      De ce point de vue, l’écosystème macOS me semble bien meilleur

    • Je développe un langage de programmation compilé pour plusieurs plateformes, et la signature comme la notarisation ne collent pas du tout à ce processus
      Ce genre de système de signature n’est qu’un outil de contrôle, avec un risque d’abus comme dans l’affaire Epic
      S’il n’est pas possible d’exécuter raisonnablement des binaires non signés, je considère la plateforme comme fermée et je ne la supporte pas
      Les plateformes fermées comme iOS ou Android peuvent être partiellement remplacées par des PWA
      En revanche, j’ai de moins en moins confiance dans le fait que Google continuera à autoriser l’exécution d’apps auto-signées

    • Je ne connais que deux cas où Apple a révoqué des certificats pour des apps hors App Store
      L’un concernait la Research App de Facebook, l’autre Screenwise Meter de Google
      Dans les deux cas, il s’agissait d’apps assimilables à des spywares visant des adolescents, et la révocation du certificat a aussi paralysé leurs outils internes
      Ensuite, Screenwise Meter semble être revenue sur l’App Store
      Articles associés : Wired, EFF

    • Environ la moitié des apps de mon dossier Applications ne sont pas notarisées, et en pratique ça ne pose pas vraiment de problème

    • Après notarisation, le stapled ticket (ticket attaché) est optionnel
      Si le ticket n’est pas attaché, l’utilisateur doit vérifier l’état de la notarisation via une connexion Internet

  • En développant AppBundler.jl, j’ai accumulé beaucoup de critiques sur la structure des apps macOS
    L’obligation de la structure du dossier Frameworks paraît propre visuellement, mais en pratique l’empaquetage est pénible, donc je contourne avec un dossier Libraries
    Le plus gros problème, c’est la signature du code — devoir signer chaque binaire donne l’impression d’un énorme gaspillage
    J’ai du mal à comprendre pourquoi on rend ça si compliqué alors qu’on pourrait simplement regrouper les hash de fichiers et signer une seule fois
    De plus, le fait que les entitlements ne s’appliquent qu’au binaire lanceur est aussi inefficace
    Comme les critères de notarisation se durcissent avec le temps, une app peut très bien cesser soudainement de passer plus tard

  • J’ai adhéré à l’Apple Developer Program pour signer et notariser une app Tauri, et j’échoue depuis 3 semaines
    Je n’ai pas de Mac, donc j’ai essayé avec GitHub Actions, mais on m’a dit qu’une première notarisation prend souvent longtemps
    J’ai déjà dépensé presque 100 $ en coûts GitHub, et la notarisation ne passe toujours pas
    Le support Apple refuse de m’aider parce que je n’ai pas de Mac et que j’utilise Tauri
    Le processus d’authentification de l’API de notarisation est aussi un cauchemar — il faut générer un JWT en PKCS8, la documentation est quasi inexistante, donc j’ai dû écrire moi-même un programme Node
    C’est de loin la pire expérience développeur (DX) que j’aie connue jusqu’ici

    • On m’a conseillé d’acheter un Mac mini d’occasion à 150 $ et de signer avec ça
      Essayer de résoudre ça sans matériel Apple serait une perte de temps
  • La première capture d’écran de l’OS m’a fait un choc
    Avant, l’UI était pratique et épurée, alors qu’aujourd’hui les coins arrondis et les icônes façon bulles ne font que gaspiller de l’espace
    Cela dit, la qualité du matériel Mac reste suffisamment bonne pour m’empêcher de passer sur ThinkPad

    • Les coins arrondis sont au contraire une fonction bénéfique pour la vision humaine
      Certaines études indiquent que les angles vifs provoquent de la fatigue visuelle
      Article associé : Round Rects Are Everywhere

    • Je n’aime pas non plus les versions récentes de macOS, mais cette capture n’est pas parfaite non plus
      Il y a trop de lignes et pas assez de couleur, ce qui disperse le regard
      Personnellement, je trouvais que l’Aqua UI de l’époque Leopard offrait un bon équilibre entre densité d’information et profondeur visuelle

    • Si on regarde le ratio en pixels, l’ancienne UI occupait en fait davantage d’espace
      Avec une définition 5K, les MacBook Pro modernes sont plus efficaces
      Les anciens Mac avaient déjà eux aussi des coins légèrement arrondis
      Référence : Infinite Mac

    • Un ordinateur n’est pas seulement un outil de travail, c’est aussi un outil de plaisir
      Mais les UI actuelles donnent quand même l’impression de s’être trop éloignées de l’aspect pratique

    • La majeure partie de l’écran n’est remplie que d’informations inutiles du style 101101, donc difficile de parler d’interface pratique

  • Il est faux de dire que sur macOS c’est launchd qui exécute les outils en ligne de commande
    En réalité, comme sur les autres systèmes UNIX, ils sont lancés depuis le shell via fork/spawn

  • Le système de bundles de NeXTSTEP a inspiré la conception des fichiers JAR de Java

    • Mais un JAR n’est en pratique qu’un fichier ZIP avec une extension changée
  • Sur le Mac OS classique, les apps Power Mac stockaient le code PPC dans la fourche de données
    C’était aussi le cas des binaires CFM-68K, et les ressources CODE n’étaient utilisées que pour l’ancien code 68K

  • J’ai un bon souvenir de l’époque où l’on modifiait les apps avec ResEdit

  • Comme dans le dernier diagramme, voir la bureaucratie exploser n’est pas bon signe
    Ça donne encore moins de raisons de « mettre à niveau » vers macOS 26

    • Certains répondent qu’il ne faut pas non plus dramatiser parce que quelques dossiers ont été ajoutés au bundle d’app
  • La structure actuelle est bien le « standard » de macOS, mais ce n’est pas la seule méthode
    Si le RPATH est bien configuré, on peut faire passer la notarisation avec des bibliothèques placées dans n’importe quel sous-dossier
    Par exemple, le chemin AppName.App/Contents/Libraries fonctionne aussi
    Cela dit, l’intérêt concret de cette approche est presque nul, et parmi la centaine d’apps de mon système, aucune n’utilise de dossier /Libraries

    • Sur iOS, cet aspect est bien plus strict et opaque
      Il faut impérativement utiliser le format .framework plutôt que .dylib, et cette règle n’est pas documentée
      Cela peut être détecté automatiquement lors de la soumission et entraîner un rejet