fastlane match: Remote-Mac-Signierung 2026

fastlane match: Remote-Mac-Signierung 2026

Der lokale Xcode-Build ist erfolgreich, der Remote-Mac meldet jedoch „No signing certificate“ oder hängt beim Export.

Die schnellste belastbare Lösung ist eine Kombination aus CI-Readonly-Synchronisierung, isoliertem oder temporärem Schlüsselbund, expliziter Profile-Zuordnung und Bereinigung nach jedem Build. Erst wenn Neustart, parallele Jobs, Zertifikatswechsel und eine Knotenneuerstellung bestanden sind, ist die fastlane-match-Konfiguration für macOS CI wirklich einsatzbereit.

Diese Anleitung richtet sich an DevOps-Ingenieure, die iOS-Builds auf einem Remote-Mac betreiben und trotz erfolgreicher lokaler Signierung wiederkehrende CI-Fehler sehen. Sie ist außerdem für Release-Ingenieure relevant, die mehrere Apps, Extensions oder Apple Teams auf einem langfristig laufenden Mac Runner isolieren müssen.

Der eigentliche Unterschied zwischen lokalem Build und Remote-Mac-Signierung

Ein lokaler Build funktioniert häufig, weil mehrere Voraussetzungen unbemerkt bereits erfüllt sind: Der Benutzer ist interaktiv angemeldet, der Standardschlüsselbund ist entsperrt, Xcode hat Profile zwischengespeichert und ein früherer Lauf hat die richtigen Umgebungsvariablen hinterlegt.

Auf einem Remote-Mac fehlen diese Annahmen. Ein CI-Prozess startet möglicherweise ohne grafische Sitzung. Der private Schlüssel liegt zwar im Schlüsselbund, darf aber vom Hintergrundprozess nicht verwendet werden. Oder das Profil ist vorhanden, passt aber nicht zum Bundle Identifier des Targets.

Apple beschreibt ein Provisioning Profile als Bindeglied zwischen Signierungsidentität, App ID, Zielplattform, Gültigkeitszeitraum und erlaubten Entitlements. Die Profile enthalten damit nicht nur einen Dateinamen, sondern eine überprüfbare Beziehung zwischen App und Signierungsprozess. Apple erläutert die Bestandteile von Provisioning Profiles in der offiziellen Technote TN3125.

Für die Fehlersuche sollten deshalb vier Ebenen getrennt betrachtet werden:

  1. Zertifikat: Ist die erwartete Distribution- oder Development-Identität vorhanden?
  2. Privater Schlüssel: Ist der private Schlüssel im verwendeten Schlüsselbund verfügbar und zugreifbar?
  3. Provisioning Profile: Passt das Profil zum Bundle Identifier, Team und Exporttyp?
  4. Build-Konfiguration: Verwendet Xcode tatsächlich die erwartete Identität und das erwartete Profil?

Ein fünfter Bereich kommt im Remote-Betrieb hinzu: Sitzung und Berechtigungen. Ein Schlüsselbund kann korrekt importiert sein und trotzdem in einem nicht-interaktiven Runner unbrauchbar bleiben.

Sicher protokollierbar sind beispielsweise der Name einer Signierungsidentität, der Bundle Identifier, der Profilname, der Exporttyp und der Status von codesign. Nicht in Logs gehören Passphrasen, API-Schlüssel, Repository-Zugangsdaten, private Schlüssel oder vollständige Inhalte von Geheimnisdateien. Platzhalter müssen in Beispielen ausdrücklich als solche markiert werden.

Ein einzelnes App-Target braucht eine andere Absicherung als ein Administrationslauf

Für einen regulären App-Store-Build sollte der Remote-Mac nur vorhandene Signierungsassets abrufen. fastlane match verwaltet Zertifikate und Profile in einem geschützten Speicher und synchronisiert sie auf den Build-Knoten. Die offizielle Dokumentation unterstützt dabei unter anderem Git-Speicher, Cloud-Speicher und S3-basierte Ablagen. Die aktuelle match-Dokumentation beschreibt Speicher, readonly und mehrere Bundle Identifier.

Die Aufgaben sollten klar getrennt bleiben:

  • setup_ci bereitet den CI-Schlüsselbund vor und aktiviert readonly für match.
  • match synchronisiert Zertifikate und Provisioning Profiles.
  • build_app oder gym archiviert und exportiert die Anwendung.
  • codesign, security und die Archivprüfung liefern die unabhängigen Nachweise.

Ein minimales Fastfile kann so aussehen:

platform :ios do
  lane :release do
    setup_ci

    match(
      type: "appstore",
      readonly: true,
      app_identifier: "com.example.product"
    )

    build_app(
      scheme: "Product",
      export_method: "app-store"
    )
  end
end

setup_ci erzeugt laut offizieller fastlane-Dokumentation einen temporären Schlüsselbund, schaltet match in readonly und richtet sammelbare Log- und Testergebnis-Pfade ein. Der dokumentierte Standardwert für das Schlüsselbund-Timeout beträgt 3.600 Sekunden; bei langfristigen Runnern muss geprüft werden, ob dieser Zeitraum zur tatsächlichen Jobdauer passt. Die Parameter von setup_ci sind in der offiziellen Aktionsdokumentation aufgeführt.

Das bedeutet nicht, dass jeder Build automatisch sicher ist. Die Repository-Berechtigung für den verschlüsselten match-Speicher muss lesend ausgelegt sein. Die Entschlüsselungspassphrase gehört in den Geheimnisspeicher der CI-Plattform und darf nicht als Klartext in Matchfile, Fastfile oder Shell-Skripten stehen.

Schlüsselbund, Sitzung und Berechtigungen müssen gemeinsam geprüft werden

Der häufigste Unterschied zwischen interaktivem und automatisiertem Betrieb liegt nicht im Zertifikat, sondern im Zugriff auf den privaten Schlüssel. Ein lokaler Benutzer kann den Schlüsselbund bereits entsperrt haben. Ein Hintergrund-Runner startet dagegen möglicherweise mit einem anderen Standardschlüsselbund oder ohne Zugriffskontrollfreigabe.

Für eine erste Diagnose werden keine Geheimnisse ausgegeben:

security default-keychain
security list-keychains
security find-identity -v -p codesigning

Eine typische erfolgreiche Ausgabe enthält eine gültige Codesignierungsidentität:

  1) ABCDEF1234567890 "Apple Distribution: Example Team (TEAMID1234)"
     1 valid identities found

Der genaue Name hängt vom Team und Zertifikatstyp ab. Wichtig ist der Status valid. Eine bloße .cer-Datei genügt nicht, wenn der zugehörige private Schlüssel fehlt. Apple weist ausdrücklich darauf hin, dass eine Signierungsidentität aus Zertifikat sowie öffentlichem und privatem Schlüssel besteht. Die offizielle Dokumentation zur Synchronisierung von Signierungszertifikaten beschreibt diesen Zusammenhang.

Falls der Runner einen eigenen Schlüsselbund verwendet, sollte der Ablauf innerhalb der Lane oder eines kontrollierten CI-Schritts sichtbar gemacht werden:

security default-keychain
security find-identity -v -p codesigning "$HOME/Library/Keychains/fastlane_tmp_keychain-db"

Ein fehlender Treffer bedeutet nicht zwingend, dass match falsch gearbeitet hat. Möglich sind ein falscher Pfad, eine nicht gesetzte Standardschlüsselbundliste, ein abgelaufener Schlüsselbundzugriff oder ein Import ohne privaten Schlüssel.

Die Prüfung sollte daher in dieser Reihenfolge erfolgen:

  1. Ist der verwendete Schlüsselbund tatsächlich in der Suchliste?
  2. Ist die erwartete Signierungsidentität sichtbar?
  3. Ist der private Schlüssel unter derselben Identität vorhanden?
  4. Darf der CI-Prozess auf den Schlüssel zugreifen?
  5. Wird danach ein neuer Prozess gestartet, der dieselbe Umgebung erbt?

Bei einem dauerhaften Remote-Mac ist zusätzlich die Datenschutzgrenze wichtig. Logs sollten keine Team-IDs zusammen mit vertraulichen Repository-Informationen unnötig bündeln. Zugriff auf den Signierungs-Repository, Remote-Shell und Web-Konsole sind getrennt zu protokollieren. Das erleichtert eine DSGVO-konforme Nachvollziehbarkeit, ohne private Schlüssel in zentralen Logs zu vervielfältigen.

Mehrere Targets erfordern explizite Profile-Zuordnung

Ein Haupt-Target, ein Widget und eine Notification Service Extension besitzen unterschiedliche Bundle Identifier. Ein erfolgreich synchronisiertes Profil für die Haupt-App beweist daher nicht, dass die Extension korrekt signiert wird.

match kann mehrere Bundle Identifier synchronisieren:

lane :signing_assets do
  match(
    type: "appstore",
    readonly: true,
    app_identifier: [
      "com.example.product",
      "com.example.product.widget",
      "com.example.product.notification"
    ]
  )
end

Die Beziehung zwischen Target und Profil sollte an mindestens einer Stelle ausdrücklich und reviewbar abgelegt werden. Eine sinnvolle Aufteilung lautet:

  • Matchfile: Speicherort, Branch, Team-Grunddaten und zentrale match-Optionen.
  • Fastfile: Ablauf, Profiltyp, Bundle-Identifier-Liste und CI-Verhalten.
  • Xcode Build Settings: konkrete Signierungsidentität und Profilzuordnung je Konfiguration.
  • Build-Logs: Nachweis, welches Target mit welcher Identität archiviert wurde.

Die Profile müssen nicht nur vorhanden sein. Sie müssen zum jeweiligen Target passen. Apple nennt Bundle ID, Zertifikat, Geräte- beziehungsweise Distributionskontext und Entitlements als Bestandteile der Profilprüfung. Die offizielle Übersicht zu Profilen beschreibt diese Zuordnungen.

Nach dem Archivieren sollte die Zuordnung überprüft werden:

codesign -dvvv --entitlements :- "Payload/Product.app" 2>&1
security cms -D -i "Payload/Product.app/embedded.mobileprovision" \
  -o /tmp/product-profile.plist
plutil -p /tmp/product-profile.plist

Für eine Extension wird der Pfad entsprechend angepasst. Der Nachweis muss mindestens zeigen, dass das erwartete Bundle Identifier und die erlaubten Entitlements zusammenpassen. Ein grünes build_app allein ist dafür zu schwach.

Bei macOS-Apps gelten zusätzlich andere Profilpfade und Regeln. Apple dokumentiert für macOS-Apps das eingebettete Profil unter MyApp.app/Contents/embedded.provisionprofile, während andere Apple-Plattformen typischerweise embedded.mobileprovision verwenden. Die Profilpfade und Unterschiede erklärt Apple in TN3125.

Mehrere Teams und langfristige Runner brauchen harte Isolationsgrenzen

Ein gemeinsam genutzter Remote-Mac ist nicht automatisch ein sicherer Multi-Team-Runner. Alte Zertifikate und Profile können durch Xcode-Caches oder einen dauerhaft geöffneten Schlüsselbund erneut in einen Build gelangen.

Für mehrere Teams sollten mindestens diese Grenzen getrennt werden:

  • eigener match-Speicher oder eigener Branch je Team,
  • getrennte CI-Geheimnisse,
  • eigene Schlüsselbundnamen,
  • getrennte Arbeitsverzeichnisse,
  • eigene Runner-Benutzer oder klar getrennte Job-Umgebungen,
  • explizite Team-ID und Bundle-Identifier pro Lane.

Automatische Signierung eignet sich für lokale Entwicklung und kontrollierte Entwicklungsabläufe. Für Release-CI ist eine explizite Konfiguration meist besser auditierbar. Sie macht sichtbar, welches Team, welcher Profiltyp und welches Target verwendet werden. Automatische Signierung kann dagegen Profile neu anfordern oder lokale Zustände berücksichtigen, die auf einem anderen Knoten nicht vorhanden sind.

Für einen neuen Job sollte deshalb nicht der komplette Benutzerordner aus einem vorherigen Lauf übernommen werden. Besonders kritisch sind:

  • ~/Library/MobileDevice/Provisioning Profiles/,
  • alte Build- und Archive-Verzeichnisse,
  • Schlüsselbunde,
  • temporäre Match-Dateien,
  • exportierte .p12-Dateien,
  • CI-Logs mit erweiterten Shell-Ausgaben.

Die offizielle fastlane-Dokumentation empfiehlt readonly für CI, damit der Runner keine neuen Zertifikate oder Profile erzeugt. Die readonly-Empfehlung ist Bestandteil der match-CI-Anleitung.

FAQ: Die fünf typischen Remote-Mac-Probleme

Wie wird der Schlüsselbund für fastlane match auf einem Remote-Mac eingerichtet?

Für CI sollte fastlane zuerst einen isolierten temporären Schlüsselbund anlegen. setup_ci übernimmt diese Aufgabe, setzt match in den readonly-Modus und konfiguriert die benötigten CI-Pfade. Entscheidend ist, dass der Runner auf diesen Schlüsselbund zugreifen kann. Nach dem Build müssen Schlüsselbund, importierte Zertifikate und temporäre Profile wieder entfernt oder durch den Lebenszyklus des Knotens bereinigt werden.

Warum funktioniert fastlane match lokal, aber die Signierung im CI nicht?

Ein lokaler Build nutzt häufig eine bereits entsperrte Sitzung, einen bekannten Standardschlüsselbund oder zwischengespeicherte Profile. Ein CI-Prozess besitzt diese Voraussetzungen nicht automatisch. Deshalb müssen private Schlüssel, Zertifikate, Profile, Zugriffsrechte und Xcode-Build-Einstellungen gemeinsam geprüft werden. Ein erfolgreiches Lane-Ergebnis reicht nicht aus; die erzeugte App muss anschließend mit codesign und der Archivstruktur verifiziert werden.

Sollte fastlane match im Remote-Mac-CI immer readonly verwenden?

Für reguläre CI-Läufe ist readonly die sichere Standardeinstellung. Dadurch kann der Runner vorhandene Zertifikate und Profile synchronisieren, aber keine neuen Assets erzeugen oder bestehende Signierungsdaten unkontrolliert verändern. Erzeugung, Erneuerung und Rotation gehören in einen ausdrücklich geplanten Administrationslauf mit Sicherung und Freigabe. setup_ci aktiviert readonly für CI-Szenarien automatisch.

Wie werden mehrere Targets unterschiedlichen Provisioning Profiles zugeordnet?

Jedes Target benötigt eine eindeutige Zuordnung zwischen Bundle Identifier, Profiltyp und Signierungsidentität. Die Bundle Identifier werden in match als Liste oder über eine eigene Lane synchronisiert. Die konkrete Zuordnung sollte zusätzlich in Matchfile, Fastfile oder den Xcode-Build-Einstellungen festgehalten werden. Für Extensions sind die eingebetteten Profile und die Signatur jedes Bundles separat zu prüfen.

Wie wird ein dauerhaft laufender Mac Runner von alten Signierungsdaten bereinigt?

Ein langfristiger Runner sollte nicht wie ein einmaliger Hosted Runner behandelt werden. Nach jedem Auftrag müssen temporäre Dateien, Profile, Logs mit Geheimnissen und nicht mehr benötigte Schlüsselbunddaten geprüft werden. Bei parallelen Jobs sind getrennte Arbeitsverzeichnisse und eindeutige Schlüsselbundnamen erforderlich. Ein Neustarttest, ein aufeinanderfolgender Build und ein absichtlich fehlschlagender Build zeigen, ob die Bereinigung wirklich belastbar ist.

Zertifikatswechsel, Ablauf und Knotenneuerstellung ohne vorschnellen Reset

Ein abgelaufenes oder widerrufenes Zertifikat verlangt nicht automatisch einen vollständigen Reset. Zuerst muss geklärt werden, welches Asset ungültig ist:

security find-identity -v -p codesigning
find "$HOME/Library/MobileDevice/Provisioning Profiles" \
  -type f -name "*.mobileprovision" -print

Danach folgt die Wiederherstellung in einer kontrollierten Reihenfolge:

  1. Zertifikatsstatus und Profilstatus im Apple-Developer-Konto prüfen.
  2. Feststellen, ob nur ein Profil abgelaufen oder auch ein Zertifikat widerrufen wurde.
  3. Einen administrativen match-Lauf außerhalb des normalen CI-Jobs planen.
  4. Neue Assets verschlüsselt im vorgesehenen Speicher ablegen.
  5. Den Remote-Mac mit readonly neu synchronisieren.
  6. Archiv, Export und Signatur des resultierenden Artefakts prüfen.
  7. Alte Assets erst nach erfolgreicher Verifikation entfernen.

Apple beschreibt, dass Profile nach Ablauf, Widerruf eines Zertifikats oder Änderungen an App-Diensten neu erzeugt werden müssen. Die offizielle Anleitung zur Erneuerung und Entfernung von Provisioning Profiles finden Sie in der Apple-Dokumentation.

Ein destruktiver Reset von Zertifikaten oder Profilen ist daher kein allgemeiner Reparaturbefehl. Vorher müssen Release-Kanäle, bereits verteilte Testversionen, Teamzugriffe und eine Sicherung des verschlüsselten match-Speichers geprüft werden. Ein falsch gesetzter Reset kann funktionierende lokale Entwicklungsumgebungen und andere Apps desselben Teams beschädigen.

Für eine Knotenneuerstellung ist ein leerer Testknoten wertvoller als ein weiterer Versuch auf dem produktiven Runner. Der Test sollte zeigen:

  • Installation der vorgesehenen Xcode- und fastlane-Version,
  • Zugriff auf den match-Speicher,
  • Import in den isolierten Schlüsselbund,
  • Archiv mit jedem relevanten Target,
  • erfolgreicher Export,
  • Neustart und erneuter Build,
  • Bereinigung nach einem absichtlich fehlschlagenden Lauf.

Entscheidungsmatrix für den passenden Remote-Mac-Betrieb

Betriebsmodell Schlüsselbundstrategie match-Modus Geeignet für Kritischer Nachweis
Einmaliger Build-Knoten Temporärer Schlüsselbund readonly: true Migration, Einzelrelease, Wiederherstellung Signaturprüfung nach dem Export
Dauerhafter Einzel-Team-Runner Isolierter Schlüsselbund je Job oder kontrollierter Benutzer readonly: true Regelmäßige App-Store-Builds Neustart, Folgejob und Bereinigung
Mehrere Apps eines Teams Gemeinsamer Speicher mit expliziter Bundle-Identifier-Liste readonly: true Haupt-App und Extensions Profilprüfung je Target
Mehrere Apple Teams Getrennte Speicher, Geheimnisse und Schlüsselbunde readonly: true Agenturen, Plattformteams, Shared Runner Keine Cross-Team-Wiederverwendung
Zertifikatsrotation Administrativer Lauf mit Sicherung temporär schreibend, danach CI-readonly Ablauf, Widerruf, neue Entitlements Neuarchivierung und dokumentierter Rückweg

Für laufende Builds muss nicht automatisch ein eigener physischer Mac gekauft werden. Ein selbst betriebener Mini-Rechner kann bei dauerhaft hoher Auslastung, benötigten Hardware-Schnittstellen oder strengen lokalen Compliance-Vorgaben sinnvoll sein. Er verursacht jedoch Anschaffung, Wartung, Ersatzteilrisiko, Stromversorgung und die Verantwortung für sichere Fernzugriffe.

Eine zeitweise genutzte Remote-Mac-Umgebung passt besser zu Migrationen, saisonalen Releases, Testphasen und einer Knotenneuerstellung. Vor der Entscheidung sollten verfügbare Zugriffsrechte, tatsächliche Xcode-Anforderungen, Datenhaltung und die geplante Nutzungsdauer geprüft werden. Einen Überblick über nutzungsabhängige Mac-Modelle und Mietoptionen bietet die Übersicht zu Mac-Mietpreisen.

Schluss: Erst die Signierung beweisen, dann den Knoten als produktiv betrachten

Ein lokaler Build beweist nur, dass eine bestimmte Benutzerumgebung signieren konnte. Er beweist nicht, dass ein Remote-Mac nach einem Neustart, bei parallelen Jobs oder nach einer Zertifikatsrotation reproduzierbar arbeitet.

Die belastbare Zielarchitektur lautet deshalb: setup_ci, match --readonly, isolierter Schlüsselbund, explizite Bundle-Identifier-Zuordnung, unabhängige Signaturprüfung und definierte Bereinigung. Wer diese Punkte dokumentiert und mit einem Knotenneuaufbau testet, erhält einen nachvollziehbaren macOS-CI-Prozess statt eines zufällig funktionierenden Rechners.

Der Kauf eines eigenen Mac mini bleibt bei dauerhaft hoher Grundlast und benötigten physischen Schnittstellen die bessere Lösung. Für eine einmalige Migration entstehen dabei jedoch unnötige Anschaffungskosten, langfristige Wartung und ein eigener Ausfallpfad. Eine zeitweise gemietete Remote-Mac-Umgebung kann für Signaturtests, Release-Phasen und die Validierung eines neuen CI-Designs flexibler sein. SFTPMAC bietet dafür einen Remote-Mac mit vollständigen Zugriffsrechten, sodass ein Team den Wiederaufbau, Neustart und die Signaturprüfung unter realen Bedingungen durchführen kann. Die verfügbaren Optionen sind auf der deutschen SFTPMAC-Übersicht einsehbar.