Sicherheit und Betrieb des Backport-Builders
Build-Werkzeuge — KEINE Laufzeitabhängigkeit. Diese Seite befasst sich mit dem Betrieb der Build-Pipeline und dem in sie gesetzten Vertrauen. Die Sicherheitshaltung der PDF-Engine selbst ist in der Engine-Dokumentation beschrieben, nicht hier.
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Der Builder transformiert Quellcode, den er nicht selbst verfasst, und gibt eine Distribution aus, an der nicht entwickelt wird. Daraus ergibt sich sein Sicherheitsmodell. Die Vertrauensgrenze liegt beim Quell-Checkout und bei der Toolchain. Das ausgegebene Artefakt ist schreibgeschützt und maschinell erzeugt. Die Lizenzaufteilung zwischen öffentlichem Paket und Pro-Paket ist im Code festgelegt.
Die Vertrauensgrenze
Abschnitt betitelt „Die Vertrauensgrenze“Die Eingaben des Builders sind die Quell-Repositorys und die fixierte Toolchain. Seine Ausgabe ist ein daraus abgeleitetes Artefakt. Drei Eigenschaften gelten:
- Die generierte Distribution ist schreibgeschützt und maschinell erzeugt. Sie wird als Versions-Tags veröffentlicht, nicht als Branches dieses Repositorys. Entwicklung, Fehlerberichte und Feature-Anfragen gehen an die ursprünglichen
nextpdf/*-Quell-Repositorys, niemals an den generierten Baum. Nachprüfbar anhand des Warnblocks in derREADME.mddes Projekts und der.github/workflows/build.yml(das Release committet und taggt den generierten Baum von Grund auf neu). - Der Geltungsbereich des Release-Tokens ist eng gefasst.
secrets.BACKPORT_TRIGGER_TOKENautorisiert das Klonen der Quell-Repositorys am Release-Tag. Es wird ausschließlich in den Quell-Checkout-Schritten referenziert. Nachprüfbar anhand derbuild.yml(Verwendung vonGH_TOKEN). - Die Aufteilung der CI-Runner ist bewusst gewählt. Vertrauenswürdige Ereignisse laufen auf selbst gehosteten PHP-Runnern; Fork-Pull-Requests und Dependabot-Läufe laufen zwingend auf GitHub-gehosteten Runnern. Nicht vertrauenswürdiger Code wird niemals im vertrauenswürdigen Runner-Pool ausgeführt. Nachprüfbar anhand der
.github/workflows/0-ci.yml(dieruns-on-Bedingung).
Lieferketten-Haltung
Abschnitt betitelt „Lieferketten-Haltung“- Die Toolchain ist in
composer.jsoneingeschränkt. Rector^2.0, PHPStan^2.1, PHPUnit^13.0und dassymfony/polyfill-*-Set. Der Builder hat keine NextPDF-Laufzeitabhängigkeit; deshalb kann eine Kompromittierung eines NextPDF-Laufzeitpakets den Builder nicht erreichen. Nachprüfbar anhand dercomposer.json. - Abhängigkeits-Updates sind bot-gesteuert und abgesichert. Es gibt eine Dependabot-Konfiguration und einen Auto-Merge-Workflow; Dependabot-Läufe sind auf GitHub-gehostete Runner festgelegt und durchlaufen vor dem Merge dennoch das vollständige CI-Gate (PHPStan, Tests, Dry-Run). Nachprüfbar anhand der
.github/dependabot.ymlund.github/workflows/0-ci.yml,9-dependabot-auto-merge.yml. - Die Ausgabe schließt den Build-Zustand aus. Das Release-Archiv wird ohne
vendor/und.git/gezippt, sodass das veröffentlichte Artefakt Quellcode und das generierte Manifest enthält, nicht den eigenen Abhängigkeitsbaum des Builders. Nachprüfbar anhand derbuild.yml(zip ... -x '*/vendor/*' '*/.git/*'). - Statische Analyse sichert den Build-Code ab.
composer analyseführt PHPStan auf Level 10 fürrector/rulesundscriptsbei jedem Push und Pull-Request gegen einen der beiden permanenten Branches aus. Dies geschieht vor jedem Dry-Run. Nachprüfbar anhand dercomposer.jsonund der0-ci.yml.
Das Syntax-Validierungs-Gate
Abschnitt betitelt „Das Syntax-Validierungs-Gate“Das Build-Skript prüft die Ausgabe lokal nicht auf Syntaxfehler. Der Grund ist, dass der Build-Host ein neueres PHP ausführt als das Ziel. Das maßgebliche Gate befindet sich im Release-Workflow. Nach dem Build wechselt der Runner zum Ziel-PHP und führt php -l über output/src aus; bei jedem Parse- oder schwerwiegenden Fehler schlägt das Release fehl. Das Artefakt wird anschließend in der Validierungsmatrix installiert und ausgeführt — PHP 8.1 bis 8.4 für die PHP-8.1-Lane, PHP 7.4 und 8.0 für die PHP-7.4-Lane. Eine Distribution, die eine Ziel-Laufzeitumgebung ablehnen würde, erreicht kein Release. Nachprüfbar anhand von scripts/build.php (validateOutput()) und der .github/workflows/build.yml (die Syntax-Check- und validate-*-Jobs).
Dies ist eine auf beobachtetem Verhalten beruhende Garantie, beschränkt auf die Laufzeitumgebungen, die die Pipeline durchläuft. Sie stellt keine Konformitätszertifizierung dar. Sie sichert nicht zu, dass das transformierte Programm über die Syntaxakzeptanz und die projekteigene Test-Suite hinaus korrekt ist.
Lizenzaufteilung
Abschnitt betitelt „Lizenzaufteilung“Die beiden erzeugten Pakete tragen unterschiedliche Lizenzen; festgelegt ist das in scripts/adjust-composer.php:
| Paket | Lizenzfeld | Gesetzt durch |
|---|---|---|
nextpdf/backport | Apache-2.0 | generatePublicComposer() |
nextpdf/backport-pro | proprietary | generateProComposer() |
Das Builder-Repository selbst steht unter Apache-2.0 (composer.jsonlicense). Seine CHANGELOG.md dokumentiert eine frühere Umlizenzierung von LGPL-3.0-or-later auf Apache-2.0. Vor dieser Änderung veröffentlichte Versionen bleiben unter der älteren Lizenz und weiterhin abrufbar, während jede neue Version unter Apache-2.0 steht. Die Pro-Distribution ist proprietär, wird nur für das PHP-8.1-Ziel erzeugt und erfordert phpseclib/phpseclib ^3.0. Nachprüfbar anhand von CHANGELOG.md, composer.json und scripts/adjust-composer.php.
Betriebliche Garantien und ihre Grenzen
Abschnitt betitelt „Betriebliche Garantien und ihre Grenzen“Die Pipeline garantiert nur, was der Code durchsetzt:
- Abbruch beim ersten Fehler. Der Build bricht bei der ersten fehlgeschlagenen Stufe mit einem benannten Fehler ab. Eine unvollständige Distribution wird niemals veröffentlicht, da die Release-Jobs von einem erfolgreichen Build und einer erfolgreichen Validierung abhängen. Nachprüfbar anhand von
scripts/build.php(step()) und dembuild.yml-Job-needs. - Serialisierte Builds. Die Concurrency-Gruppe
backport-buildmitcancel-in-progress: falseverhindert, dass zwei Quell-Releases um dasselbe Release-Tag konkurrieren. Nachprüfbar anhand derbuild.yml. - Reproduzierbare Eingaben. Die Pipeline klont vor dem Build jedes Quell-Repository am genauen Release-Tag. Nachprüfbar anhand der
build.yml(--branch "${TAG}").
Was sie nicht für sich beansprucht:
- Sie zertifiziert weder Standardkonformität noch vollständige PHP-Versionskompatibilität noch die Korrektheit des transformierten Programms über die Syntaxakzeptanz und die Test-Suite hinaus.
- Das Downgrade entfernt die zur Laufzeit erzwungene Unveränderlichkeit (Entfernen von
readonly). Code, der sich darauf verlassen hat, dass die Laufzeitumgebung einen Schreibzugriff auf eine readonly-Eigenschaft ablehnt, verliert diesen Schutz in der heruntergestuften Ausgabe. Dies ist ein dokumentierter, beabsichtigter Kompromiss zugunsten der clone-with-Sicherheit — siehe /integrations/backport/troubleshooting/.
Ein Problem melden
Abschnitt betitelt „Ein Problem melden“Sicherheitsprobleme im Builder richten sich nach der SECURITY.md des Repositorys: Melden Sie sie über ein GitHub Security Advisory oder den Sicherheitskontakt, nicht über ein öffentliches Issue. Probleme im generierten Code werden bei den ursprünglichen Quell-Repositorys eingereicht, da der generierte Baum maschinell erzeugt wird und nicht als Entwicklungsbasis dient. Nachprüfbar anhand der SECURITY.md und der README.md des Projekts.
- /integrations/backport/overview/ — was der Builder ist und was er produziert.
- /integrations/backport/production-usage/ — Betrieb der Release-Pipeline.