Salta ai contenuti

Sicurezza e aspetti operativi del builder di backport

Strumenti di build — NON una dipendenza di runtime. Questa pagina riguarda il funzionamento della pipeline di build e il relativo modello di fiducia. La postura di sicurezza del motore PDF è documentata insieme al motore, non qui.

Il builder trasforma sorgenti di cui non è autore e produce una distribuzione che non viene sviluppata qui. Il suo modello di sicurezza deriva da questo fatto. Il confine di fiducia è costituito dal checkout dei sorgenti e dalla toolchain. L’artefatto prodotto è in sola lettura e generato dalla macchina. La suddivisione delle licenze tra il pacchetto pubblico e quello Pro è fissata nel codice.

Gli input del builder sono i repository dei sorgenti e la toolchain vincolata. Il suo output è un artefatto derivato. Valgono tre proprietà:

  • La distribuzione generata è in sola lettura e prodotta dalla macchina. Viene pubblicata come tag di versione, non come branch di questo repository. Lo sviluppo, le segnalazioni di bug e le richieste di funzionalità vanno indirizzati ai repository dei sorgenti originali nextpdf/*, mai all’albero generato. Verificato a fronte del blocco di avvertenza README.md del progetto e di .github/workflows/build.yml (il rilascio committa e tagga l’albero generato da zero).
  • L’ambito del token di rilascio è ristretto. secrets.BACKPORT_TRIGGER_TOKEN autorizza la clonazione dei repository dei sorgenti al tag di rilascio. È referenziato solo nei passaggi di checkout dei sorgenti. Verificato a fronte di build.yml (uso di GH_TOKEN).
  • La separazione dei runner CI è deliberata. Gli eventi attendibili vengono eseguiti su runner PHP self-hosted; le pull request da fork e le esecuzioni di Dependabot sono forzate sui runner ospitati da GitHub. Il codice non attendibile non viene mai eseguito nel pool di runner attendibili. Verificato a fronte di .github/workflows/0-ci.yml (la condizione runs-on).
  • La toolchain è vincolata in composer.json. Rector ^2.0, PHPStan ^2.1, PHPUnit ^13.0 e l’insieme symfony/polyfill-*. Il builder non ha alcuna dipendenza di runtime NextPDF, quindi la compromissione di un pacchetto di runtime NextPDF non può propagarsi al builder. Verificato a fronte di composer.json.
  • Gli aggiornamenti delle dipendenze sono guidati da bot e sottoposti a gate. Esistono una configurazione Dependabot e un flusso di auto-merge; le esecuzioni di Dependabot sono vincolate ai runner ospitati da GitHub e attraversano comunque l’intero gate CI (PHPStan, test, dry-run) prima del merge. Verificato a fronte di .github/dependabot.yml e .github/workflows/0-ci.yml, 9-dependabot-auto-merge.yml.
  • L’output esclude lo stato di build. L’archivio di rilascio è compresso in zip con vendor/ e .git/ esclusi; l’artefatto pubblicato trasporta quindi i sorgenti e il manifest generato, non l’albero delle dipendenze del builder stesso. Verificato a fronte di build.yml (zip ... -x '*/vendor/*' '*/.git/*').
  • L’analisi statica funge da gate per il codice di build. composer analyse esegue PHPStan al livello 10 su rector/rules e scripts a ogni push e pull request verso entrambi i branch permanenti. Viene eseguita prima di qualsiasi dry-run. Verificato a fronte di composer.json e 0-ci.yml.

Lo script di build non verifica localmente la sintassi dell’output, perché l’host di build esegue una versione di PHP più recente rispetto al target. Il gate autorevole si trova nel flusso di rilascio. Dopo la build, il runner passa al PHP target ed esegue php -l su output/src, facendo fallire il rilascio in presenza di qualsiasi errore di parsing o errore fatale. L’artefatto viene quindi installato ed esercitato attraverso la matrice di validazione — da PHP 8.1 a 8.4 per la corsia PHP 8.1, PHP 7.4 e 8.0 per la corsia PHP 7.4. Una distribuzione che un runtime target rifiuterebbe non arriva al rilascio. Verificato a fronte di scripts/build.php (validateOutput()) e .github/workflows/build.yml (i job di verifica della sintassi e validate-*).

Questa è una garanzia di comportamento osservato, circoscritta ai runtime esercitati dalla pipeline. Non è una certificazione di conformità. Non afferma la correttezza del programma trasformato oltre l’accettazione della sintassi e la suite di test del progetto stesso.

I due pacchetti prodotti recano licenze diverse, fissate in scripts/adjust-composer.php:

PacchettoCampo licenzaImpostato da
nextpdf/backportApache-2.0generatePublicComposer()
nextpdf/backport-proproprietarygenerateProComposer()

Il repository del builder stesso è Apache-2.0 (composer.jsonlicense). Il suo CHANGELOG.md registra una precedente rilicenziazione da LGPL-3.0-or-later a Apache-2.0. Le versioni pubblicate prima di quel cambiamento rimangono soggette alla licenza precedente e restano recuperabili, mentre ogni nuova versione è Apache-2.0. La distribuzione Pro è proprietaria, viene prodotta solo per il target PHP 8.1 e richiede phpseclib/phpseclib ^3.0. Verificato a fronte di CHANGELOG.md, composer.json e scripts/adjust-composer.php.

Ciò che la pipeline garantisce, limitatamente a quanto imposto dal codice:

  • Arresto al primo fallimento. La build si interrompe alla prima fase che fallisce con un errore denominato. Una distribuzione parziale non viene mai rilasciata, perché i job di rilascio dipendono da build e validazione riuscite. Verificato a fronte di scripts/build.php (step()) e dei job needs di build.yml.
  • Build serializzate. Il gruppo di concorrenza backport-build con cancel-in-progress: false impedisce a due rilasci dei sorgenti di contendersi lo stesso tag di rilascio. Verificato a fronte di build.yml.
  • Input riproducibili. La pipeline clona ogni repository dei sorgenti al tag di rilascio esatto prima della compilazione. Verificato a fronte di build.yml (--branch "${TAG}").

Ciò che non dichiara:

  • Non certifica la conformità agli standard, la piena compatibilità tra le versioni di PHP né la correttezza del programma trasformato oltre l’accettazione della sintassi e la suite di test.
  • Il downgrade rimuove l’immutabilità imposta dal runtime (rimozione di readonly). Il codice che si affidava al runtime per rifiutare una scrittura su una proprietà readonly perde quella difesa nell’output sottoposto a downgrade. È un compromesso documentato e intenzionale a favore della sicurezza di clone-with — vedere /integrations/backport/troubleshooting/.

I problemi di sicurezza nel builder seguono il SECURITY.md del repository: segnalare tramite un GitHub Security Advisory o il contatto di sicurezza, non tramite un issue pubblico. I problemi nel codice generato vanno aperti contro i repository dei sorgenti originali, perché l’albero generato è prodotto dalla macchina e non è oggetto di sviluppo. Verificato a fronte di SECURITY.md e del README.md del progetto.

  • /integrations/backport/overview/ — che cos’è il builder e cosa produce.
  • /integrations/backport/production-usage/ — come funziona la pipeline di rilascio.