Sicherheit
Ein Dependency-Bot hält einen Token, der in jedes Repository schreiben kann, das er scannt. Und er liest Konfiguration aus allen. Das sind die Linien, die pinup hält, und was ein Repository den Bot tun lassen kann und was nicht.
- Meldungen: Sicherheitsmeldungen an die Adresse in der
SECURITY.mddes Repositories, nicht als Issue
Die Invarianten
Jeder Lauf erzeugt einen Plan vor jedem Schreibzugriff
Was sich ändert, ist in Bytes bekannt, bevor sich das erste Byte ändert.
Apply verbraucht Byte-Range-Edits, nie Abhängigkeiten
Nichts hinter dem Plan kann eine Änderung erfinden; YAML und JSON werden nie neu serialisiert.
Der Kern entscheidet, Plugins wenden an
Ein Task läuft in einem Scope, den er nicht verlassen darf; ein Pfad außerhalb verwirft sein ganzes Ergebnis.
Das strengere von zwei Labels gewinnt
Ein Analyzer lockert einen Automerge nur mit trustEffective: true.
Plugins bekommen keine Zugangsdaten
Ein Task sieht PATH, LANG, TZ und was PINUP_PLUGIN_ENV nennt; nie den Plattform-Token, nie den Signierschlüssel.
Ein Plan erklärt, warum nichts passiert
Ein gehaltenes Update trägt seinen Grund; ein abgelehntes Kommando wird genannt, nicht übersprungen.
Der Plattform-Token
Der Token ist an den Host der Instanz gebunden und, auf GitLab, an die API-Pfade, die der Bot selbst aufruft: Releases, Tags, Rohdateien, Pakete, die Gruppen-Composer-Registry, sein eigener User. Eine URL, die eine Repository-Konfiguration auf der Instanz nennt (ein customDatasources-Template, ein registryUrls-Eintrag), wird ohne ihn angefragt. Sonst könnte jeder Entwickler in jedem gescannten Repository den api-Token des Bots auf /api/v4/groups/<id>/variables richten und das Ergebnis als „Release-Liste“ lesen.
Der Registry-Zugang existiert nur für die eigene Registry des Estates (PINUP_REGISTRY_HOST), getauscht am Token-Realm der Instanz über TLS, begrenzt auf das eine Repository, das ein Lookup braucht. Jede andere Registry wird anonym gefragt.
Der GitHub-Token ist an api.github.com gebunden (oder den Enterprise-Host). Ein Redirect weg vom Host einer Plattform wird verweigert, nicht verfolgt: net/http lässt Authorization über Hosts hinweg fallen, einen PRIVATE-TOKEN-Header nicht.
Kein Token landet je in einer Datei oder einer URL. git fragt Zugangsdaten über GIT_ASKPASS ab, das ist das pinup-Binary selbst, und es antwortet nur auf einen Prompt für den Host der Plattform.
Was ein Repository entscheiden kann
Die eigene Konfigurationsdatei eines Repositories kann sich selbst deaktivieren, Versionierungen und Registries ändern, Regeln hinzufügen, Tasks anfordern. Sie kann nicht:
- ein Kommando ausführen, das
PINUP_ALLOWED_COMMANDSdes Runners nicht zulässt (geprüft am kompilierten Kommando, nach dem Templating) executionTimeoutanheben (das istPINUP_EXECUTION_TIMEOUTdes Runners)- den Plattform-Token über eine URL erreichen, die sie nennt
- außerhalb des deklarierten Scopes eines Tasks schreiben
- auf ein Label automerged werden, dem die Regeln des Runners nicht vertrauen
Commits
Jeder Commit ist signiert, wie der Runner konfiguriert ist (openpgp oder ssh mit PINUP_SIGNING_KEY), von einer Identität, für die der Schlüssel bürgt (CheckIdentity weist einen Schlüssel zurück, der den Autor nicht nennt). Der Lauf liest das Urteil der Plattform über seine eigenen Commits. Unsigniert geht nur mit dem ausdrücklichen Wort none.
Ein Branch, auf den jemand anderes committet hat, gehört dem: der Lauf baut ihn weder neu noch schließt er seinen Request, und er sagt, wessen er ist.
Meldungen
Sicherheitsmeldungen an die Adresse in der SECURITY.md des Repositories, nicht als Issue.