Der Mac ist neu gestartet und per SSH erreichbar, doch die Signatur-Pipeline bleibt offline.

Die schnellste belastbare Lösung ist eine Doppelstruktur: Ein LaunchDaemon übernimmt systemweite Gesundheits- und Wiederherstellungsaufgaben, während ein dediziertes Dienstkonto seinen CI Agent als LaunchAgent in einer echten Benutzersitzung ausführt. Genau diese Trennung passt zu den von Apple beschriebenen Startkontexten; ein LaunchDaemon sollte nicht automatisch zum Träger eines benutzergebundenen iOS-Builds gemacht werden (Apple-Dokumentation zu launchd-Jobs).

Diese Anleitung richtet sich an IT-Verantwortliche, die Mac-Build-Rechner nach Neustarts unbeaufsichtigt betreiben müssen. Sie hilft außerdem Plattformteams bei iOS-Signierung und Simulator-Tests sowie technischen Leitern, die Remote-Mac-Ressourcen anhand von Wiederherstellungsnachweisen statt nur anhand von „online“ auswählen.

01

Die Startentscheidung beginnt mit dem Ausführungskontext

„Beim Einschalten gestartet“, „nach der Anmeldung verfügbar“ und „für einen produktiven Build geeignet“ sind drei verschiedene Zustände. Ein Rechner kann per SSH antworten, obwohl noch keine grafische Benutzersitzung besteht. Ebenso kann ein Agent-Prozess laufen, ohne dass Keychain, Simulator oder Signaturberechtigungen verwendbar sind.

Apple unterscheidet bei launchd insbesondere zwischen Diensten im Systemkontext und Prozessen innerhalb einer Benutzersitzung. Daraus ergibt sich für die Architektur folgende Gegenüberstellung:

Modus Startbedingung und Identität Geeignete Aufgabe Kritische Grenze
LaunchDaemon Systemstart, Systemkontext, meist ohne interaktive Benutzersitzung Host-Prüfung, Erreichbarkeit, Wiederherstellungshelfer, Monitoring Kein verlässlicher Zugriff auf benutzergebundene Keychain- und GUI-Ressourcen
Globaler LaunchAgent Start einer Benutzersitzung, systemweit definierte Agent-Konfiguration Standardisierte Agent-Starts für kontrollierte Benutzerumgebungen Abhängigkeit von einer vorhandenen Sitzung und deren Richtlinien
Benutzerbezogener LaunchAgent Anmeldung eines dedizierten Dienstkontos CI Agent, Xcode-Build, Signierung, Simulator-Tests Sitzung, Schlüsselbund und Konto müssen nach dem Neustart tatsächlich verfügbar sein

Die Tabelle ist keine Empfehlung, jeden Dienst anhand seines Namens zuzuordnen. Entscheidend ist, welche Ressourcen der Agent benötigt. Ein reiner Host-Healthcheck kann systemweit laufen. Ein Build, der auf temporäre Schlüsselbunde, Codesignatur oder iOS Simulator zugreift, gehört dagegen in den kontrollierten Benutzerkontext.

Für das konkrete Werkzeug muss das Installationmodell separat geprüft werden. GitLab dokumentiert für seinen macOS Runner ausdrücklich den Betrieb im Benutzermodus als LaunchAgent; daraus folgt nicht, dass Jenkins, TeamCity oder ein eigener CI Agent identisch installiert werden müssen (GitLab-Anleitung für macOS Runner).

02

Warum der LaunchDaemon die Keychain nicht einfach verwenden kann

Ein LaunchDaemon startet im Systemkontext und besitzt deshalb nicht automatisch die Umgebung des Dienstkontos. Es fehlen häufig eine eingeloggte Benutzersitzung, der passende Schlüsselbundpfad, die Freigabe für private Schlüssel und die Interaktion mit Sicherheitsabfragen. Ein Prozess, der lediglich „läuft“, kann daher beim Signieren trotzdem mit einem Berechtigungs- oder Keychain-Fehler abbrechen.

Apple beschreibt die Unterschiede zwischen Login-Keychains, Datenprotectionbezogenen Keychains und den jeweiligen Zugriffsvoraussetzungen in der Technote zu Mac-Keychains (Apple-Technote zu Keychains). Für eine Produktionsfreigabe sollte das Team deshalb nicht nur launchctl list oder einen Prozessstatus prüfen, sondern einen echten Signaturvorgang ausführen.

Code-Signierung, temporärer Schlüsselbund und Benutzerkonto

Ein belastbares Dienstkonto erfüllt mindestens diese Bedingungen:

  • Das Konto ist ausschließlich für CI-Aufgaben vorgesehen und nicht als persönliches Administratorkonto angelegt.
  • Der CI Agent startet innerhalb genau dieses Kontos.
  • Der temporäre Schlüsselbund wird vor dem Build eingerichtet, mit dem vorgesehenen Passwort entsperrt und nach dem Build entfernt oder gesperrt.
  • Private Schlüssel und Zertifikate sind auf den benötigten Agenten und die benötigten Build-Schritte begrenzt.
  • Der Build erhält keine unnötige Shell- oder Netzwerkberechtigung außerhalb des definierten Arbeitsbereichs.

Die Frage „Kann der Prozess das Zertifikat sehen?“ reicht nicht aus. Zusätzlich muss geprüft werden, ob das Zertifikat zum richtigen Team gehört, ob der private Schlüssel verwendbar ist und ob der Signaturvorgang ohne interaktive Eingabe endet. Apple beschreibt die Erstellung von distribution-signiertem Code als eigenen, prüfbaren Prozess; diese Dokumentation sollte neben der unternehmensinternen Zertifikatsrichtlinie als Referenz dienen (Apple-Anleitung für distribution-signierten Code).

iOS Simulator und Fensterdienste sind Benutzerressourcen

Simulator-Tests sind nicht dasselbe wie ein Headless-Compiler-Aufruf. Der Agent kann für einen reinen Quellcode-Build ausreichend funktionieren, aber beim Start des Simulators an der fehlenden Benutzersitzung, an Fensterdiensten oder an einer nicht initialisierten Umgebung scheitern. Auch ein nicht-interaktiver SSH-Aufruf bildet nicht automatisch die Umgebung nach, in der der LaunchAgent gestartet wurde.

Der praktische Test muss deshalb im Dienstkonto erfolgen. Ein Administrator sollte den Build nicht zuerst als Root ausführen und anschließend auf das Dienstkonto übertragen. Das würde die entscheidende Grenze verdecken: Ein Build, der unter Root funktioniert, beweist nicht, dass der Produktionsagent auf seine vorgesehenen Zertifikate, Arbeitsverzeichnisse und Simulatorressourcen zugreifen kann.

03

Mac-Build-Rechner mit launchd: Die Doppelstruktur als Betriebsmodell

Die empfohlene Aufteilung besteht aus einer Systemebene und einer Benutzerebene.

Die Systemebene übernimmt nur Aufgaben, die keine Veröffentlichungsgeheimnisse benötigen:

  • Erreichbarkeit und grundlegende Speicher- oder Prozessprüfungen,
  • Erkennung eines fehlenden Agent-Prozesses,
  • Weitergabe eines klaren Wiederherstellungsstatus,
  • Auslösen eines dokumentierten Neustarts oder einer erneuten Anmeldung, sofern die Sicherheitsrichtlinie dies erlaubt,
  • Schreiben von Diagnoseinformationen in einen zentral erfassten Logpfad.

Die Benutzerebene führt den eigentlichen CI Agent aus. Dort liegen die vom Build benötigten Arbeitsverzeichnisse, Keychain-Zugriffe und Simulatorabhängigkeiten. Der Systemdienst darf diese Geheimnisse nicht lesen, um den Agenten „irgendwie“ wieder online zu bringen.

Ein minimales plist-Konzept sollte deshalb nur die notwendigen Eigenschaften enthalten. Die konkrete Label-Struktur, der Pfad zum Agenten und das Konto müssen aus der offiziellen Installationsanleitung des jeweiligen CI-Produkts übernommen werden. Für die Zustandsprüfung kann ein Administrator beispielsweise die launchd-Domänen getrennt betrachten:

sudo launchctl print system
launchctl print "user/$(id -u)"

Ein erfolgreicher Rückgabestatus 0 bestätigt dabei nur, dass der jeweilige Abfragebefehl erfolgreich war. Er bestätigt weder eine aktive Benutzersitzung noch einen registrierten Agenten oder einen erfolgreichen Signatur-Build. Diese Unterscheidung verhindert, dass ein grüner Infrastrukturcheck mit Produktionsbereitschaft verwechselt wird.

Der Benutzeragent sollte nicht durch KeepAlive Fehler verschleiern

KeepAlive kann einen Prozess nach einem unerwarteten Ende erneut starten. Das ist für kurzzeitige Störungen hilfreich, verschleiert aber eine dauerhaft fehlerhafte Konfiguration, wenn der Agent unmittelbar nach jedem Start wieder beendet wird. Deshalb müssen mindestens Exit-Status, Startanzahl, letzter Fehler und Agent-Registrierung getrennt erfasst werden.

Ein Dienst, der in einer Neustartschleife läuft, ist nicht verfügbar. Die Überwachung sollte daher nicht nur den Prozessnamen suchen, sondern zusätzlich einen Agent-Heartbeat, die Verbindung zur CI-Steuerung und einen kontrollierten Testauftrag auswerten. Ein Healthcheck darf keine Signaturgeheimnisse erhalten, nur um den Status zu ermitteln.

04

Erste Prüfstufe: Startbedingungen und Konten sauber dokumentieren

Vor einer Änderung sollte das Team eine kleine Bestandsaufnahme erstellen. Sie verhindert, dass ein vermeintliches launchd-Problem tatsächlich durch einen falschen Benutzer, einen fehlenden Schlüsselbund oder eine nicht abgeschlossene Anmeldung verursacht wird.

  1. Agentmodell identifizieren: Die offizielle Servicedokumentation des verwendeten CI Agent prüfen. Festhalten, ob der Anbieter LaunchAgent, LaunchDaemon oder einen eigenen Dienstmechanismus verlangt.
  2. Ressourcen klassifizieren: Für jeden Build markieren, ob Keychain, Code-Signierung, iOS Simulator, Fensterdienste, private Repository-Schlüssel oder nur ein Compiler benötigt werden.
  3. Konten und Domänen zuordnen: Den Namen des Dienstkontos, seine Benutzer-ID, den Arbeitsbereich und die zugehörige launchctl-Domäne dokumentieren.
  4. Startkette beschreiben: Getrennt festhalten, wann das Betriebssystem startet, wann ein verschlüsseltes Volume entsperrt wird, wann die Benutzersitzung entsteht und wann der CI Agent registriert sein muss.
  5. Abnahmekriterium definieren: Einen echten Build auswählen, der Checkout, Abhängigkeiten, Signierung und – falls erforderlich – Simulatorausführung umfasst.

Die Ergebnisse gehören in die Betriebsdokumentation, nicht nur in ein einmaliges Terminalprotokoll. Bei einem Teamwechsel oder einer macOS-Aktualisierung muss nachvollziehbar bleiben, welche Annahme für den Agenten gilt.

05

Neustart, Benutzeranmeldung und FileVault sind getrennte Wiederherstellungspunkte

Ein Mac mit aktiviertem FileVault kann nach einem vollständigen Neustart zunächst an einem Entsperrschritt stehen. Ein LaunchDaemon kann in dieser Phase nicht beweisen, dass ein verschlüsseltes Volume bereits für den produktiven Build verfügbar ist. Auch eine per Remoteverwaltung ausgelöste Anmeldung darf nicht stillschweigend als sichere Standardlösung angenommen werden; sie muss zur Unternehmensrichtlinie, zur Geräteverwaltung und zum Schutz der Anmeldedaten passen.

Apple beschreibt die Rolle von FileVault und der Preboot- beziehungsweise Entsperrphase in den Sicherheitsinformationen zu macOS (Apple-Sicherheitsleitfaden zu FileVault). Für die Betriebsfreigabe muss deshalb dokumentiert werden, welcher Wiederanlauf tatsächlich unterstützt wird:

  • Geplanter Neustart: Der Rechner wird kontrolliert neu gestartet, anschließend werden Netzwerk, Benutzerkonto, Agent und Build geprüft.
  • Ungeplanter Neustart: Der Test simuliert einen unerwarteten Reboot, ohne dass ein erfolgreicher Prozessstatus vorab angenommen wird.
  • Strom- oder Hostunterbrechung: Nach der Rückkehr wird geprüft, ob der Anbieter den Rechner erreichbar macht und ob der Benutzerkontext wiederhergestellt werden kann.
  • Abmeldung: Der Benutzer wird beendet oder die Sitzung läuft aus; anschließend muss klar sein, ob der Agent bewusst offline bleibt oder durch eine freigegebene Anmeldelogik wieder startet.
  • FileVault-Szenario: Das Team hält fest, ob eine manuelle Entsperrung erforderlich ist und wie ein Remote-Mac-Betrieb diesen Zustand meldet.

Die Apple-Dokumentation zu automatischen Anmeldeszenarien weist ausdrücklich auf sicherheitsrelevante Konsequenzen hin; eine automatische Anmeldung darf nicht als bloße Komfortoption in eine Produktionsarchitektur übernommen werden (Apple-Support zu automatischer Anmeldung).

06

Die Remote-Abnahme braucht vier voneinander unabhängige Belege

Die Freigabe eines Mac-Build-Rechners sollte nicht mit „SSH funktioniert“ enden. Ein belastbares Protokoll verbindet vier Nachweise:

  1. Host erreichbar: SSH oder die vorgesehene Fernwartung antwortet nach dem Neustart.
  2. Benutzerkontext vorhanden: Das Dienstkonto ist in der erwarteten Domäne aktiv; Arbeitsverzeichnis und Umgebungsvariablen stimmen.
  3. Agent registriert: Der CI Agent ist bei der Steuerung verbunden und nimmt einen Testauftrag an.
  4. Produktionsbuild erfolgreich: Checkout, Build, Keychain-Zugriff, Signierung und gegebenenfalls Simulatorlauf enden ohne manuelle Eingabe.

Für jeden Nachweis gehören Zeitpunkt, Hostkennung, Agent-Version, relevante Logzeilen und Rückgabestatus in das Abnahmeprotokoll. Passwörter, private Schlüssel und vollständige Token dürfen dort nicht erscheinen.

Ein möglicher Diagnoseausschnitt kann bewusst knapp bleiben:

id
launchctl print "user/$(id -u)"
security list-keychains
xcodebuild -version

Diese Befehle liefern Orientierung, sind aber noch kein Produktionsnachweis. Die Ausgabe von security list-keychains zeigt beispielsweise nicht automatisch, dass der benötigte private Schlüssel entsperrt und für den vorgesehenen Prozess zugelassen ist. Erst der reale, signierte Testauftrag schließt diese Lücke.

07

Sicherheitsentscheidung: Root, Dienstkonto oder gemeinsames Administratorkonto

Ein gemeinsames Administratorkonto senkt kurzfristig den Einrichtungsaufwand, vergrößert aber die Beweislücke: Mehrere Personen und Prozesse können dieselben Arbeitsbereiche, Schlüssel und Logs verändern. Root beseitigt diese Grenze nicht, sondern erweitert den möglichen Schaden bei einem kompromittierten Build-Schritt.

Für die meisten Teams ist ein dediziertes CI-Konto die kontrollierbarere Option. Seine Rechte sollten auf den Buildzweck begrenzt werden. Der LaunchDaemon darf den Agenten nicht mit zusätzlichen Privilegien ausstatten, nur weil die Wiederherstellung sonst unbequem ist. Systemweite Reparaturaktionen müssen als eigene, auditierbare Funktionen behandelt werden.

Apple weist bei Daemons auf deren systemweiten Charakter und die daraus entstehenden Sicherheits- und Betriebsfolgen hin (Apple-Dokumentation zu Daemons). Ergänzend sollte die interne Sicherheitsrichtlinie festlegen:

  • Welche Netzwerkziele ein Build erreichen darf,
  • ob Arbeitsbereiche nach jedem Auftrag bereinigt werden,
  • wie lange Signaturmaterial auf dem Rechner verbleibt,
  • wer einen Agenten neu registrieren oder einen Host neu starten darf,
  • welche Ereignisse an ein zentrales Logging- oder SIEM-System weitergeleitet werden.

Für DSGVO-relevante Projekte müssen außerdem Quellcode, Artefakte, Logs und Zertifikatsdaten nach Standort, Aufbewahrung und Zugriff bewertet werden. Ein Remote-Mac-Angebot ist nur dann für die Organisation geeignet, wenn diese Punkte vertraglich und technisch nachvollziehbar beantwortet werden.

08

Beobachtbarkeit entscheidet über die langfristige Wartbarkeit

Ein funktionierender Start am Einführungstag sagt wenig über den Betrieb nach einem macOS- oder Agent-Update aus. Für jede Änderung sollte ein isolierter Knoten oder ein gesondertes Wartungsfenster vorgesehen werden. Vor der Produktionsfreigabe sind mindestens folgende Informationen zu vergleichen:

  • launchd-Domäne und Label des Dienstes,
  • Konto und Prozess-ID,
  • letzter Start- und Exit-Status,
  • Anzahl der Neustarts,
  • Agent-Version und macOS-Version,
  • Zeitpunkt der letzten erfolgreichen Registrierung,
  • Ergebnis des signierten Testauftrags,
  • Ursache eines fehlenden Benutzerkontexts.

Ein Logeintrag „Agent offline“ reicht nicht. Die Plattform muss unterscheiden können, ob der Prozess abgestürzt ist, die Sitzung fehlt, das Volume noch gesperrt ist, ein Zertifikat nicht zugreifbar war oder der CI-Dienst den Agenten abgelehnt hat.

Die Konfiguration sollte deshalb nicht blind mit KeepAlive versehen werden. Zuerst muss geklärt werden, ob der Prozess wegen eines falschen Kontos, einer fehlenden Umgebungsvariable oder eines beschädigten Arbeitsbereichs endet. Danach kann ein kontrollierter Neustartmechanismus aktiviert werden.

09

Freigabe-Checkliste für Mac-Build-Rechner

Die folgende Liste kann direkt in ein internes Abnahme- oder Änderungsprotokoll übernommen werden:

  • [ ] Das offizielle Startmodell des verwendeten CI Agent ist dokumentiert.
  • [ ] LaunchDaemon, globaler LaunchAgent und benutzerbezogener LaunchAgent sind eindeutig unterschieden.
  • [ ] Das Dienstkonto und seine Benutzer-ID sind festgelegt.
  • [ ] Ein reiner Systemcheck benötigt keine Signaturgeheimnisse.
  • [ ] Der CI Agent startet innerhalb der vorgesehenen Benutzersitzung.
  • [ ] Ein temporärer Schlüsselbund wird reproduzierbar erstellt, entsperrt und wieder bereinigt.
  • [ ] Ein echter signierter iOS- oder macOS-Build läuft ohne manuelle Eingabe.
  • [ ] Ein Simulator-Test wurde separat vom reinen Compilerlauf geprüft.
  • [ ] SSH-Erreichbarkeit wird nicht als Beweis für Produktionsbereitschaft gewertet.
  • [ ] Geplanter Neustart und unerwarteter Neustart wurden getestet.
  • [ ] Das Verhalten bei Abmeldung ist dokumentiert.
  • [ ] Das FileVault-Entsperrszenario ist mit der Sicherheitsrichtlinie abgestimmt.
  • [ ] Agent-Registrierung, Exit-Status und Neustartanzahl werden protokolliert.
  • [ ] Ein Update des Agenten wurde auf einem isolierten Knoten getestet.
  • [ ] Remote-Neustart und Wiederanmeldung besitzen einen klaren Verantwortlichen.
  • [ ] Für einen Ausfall existiert ein getesteter Ersatzknoten oder ein definierter Rückfall.

Werden die letzten drei Punkte nicht erfüllt, ist der Knoten nicht vollständig ausfallsicher, selbst wenn der Agent im Normalbetrieb zuverlässig arbeitet.

10

Bestehenden Knoten nachbessern oder Remote-Mac-Kapazität ergänzen

Ein vorhandener Mac kann meist nachgebessert werden, wenn ein dediziertes Konto, eine kontrollierte Benutzersitzung, ein dokumentierter FileVault-Prozess und ein unabhängiger Ersatzpfad vorhanden sind. Fehlt dagegen die Möglichkeit, eine Sitzung remote und regelkonform wiederherzustellen, bleibt die Wiederanlaufkette an manueller Intervention hängen.

Auch bei eigener Hardware entstehen dabei versteckte Betriebskosten: Ersatzgeräte, Vor-Ort-Zugriff, Lagerung von Signaturmaterial, Wartungsfenster und die Zeit für die Ursachenanalyse. Eine Übersicht zu verfügbaren Mac-Ressourcen kann bei der Kapazitätsplanung als Vergleichspunkt dienen. Für die Beschaffung sollten jedoch nicht nur Arbeitsspeicher oder Prozessor betrachtet werden, sondern auch Root-Zugriff, Remote-Neustart, Benutzerisolation, Laufzeitmodell und die dokumentierte Wiederherstellung.

Ein gemieteter Remote-Mac ist nicht in jedem Fall die beste Lösung. Bei dauerhaft hoher Auslastung, zwingender lokaler Peripherie, speziellen Netzwerkfreigaben oder langfristiger Abschreibung kann eigene Hardware wirtschaftlicher sein. Für temporäre CI-Spitzen, neue Projekte und Teams ohne belastbare Remote-Recovery ist eine verwaltete Mac-Ressource dagegen oft leichter in eine geprüfte Wiederanlaufstrategie einzubinden. NodeMini sollte dabei nicht nur nach dem Monatsbetrag, sondern nach den tatsächlich gelieferten Zugriffs- und Wiederherstellungsnachweisen bewertet werden; weitere Informationen zur Beschaffung eines Mac für Unternehmensumgebungen helfen bei dieser Gegenüberstellung.

Die zentrale Entscheidung lautet deshalb nicht „LaunchAgent oder LaunchDaemon“. Für produktive iOS- und macOS-Builds ist die tragfähige Architektur ein LaunchDaemon für systemweite Wiederherstellung und Überwachung plus ein LaunchAgent im dedizierten Dienstkonto für Keychain, Signierung und Simulator. Wenn der vorhandene Rechner diese Trennung und die fünf Wiederanlaufnachweise nicht liefern kann, sollte die IT-Abteilung vor dem nächsten Produktionsausfall entweder den Knoten gezielt nachbessern oder eine Remote-Mac-Kapazität mit klarer Recovery- und Ersatzplanung evaluieren.