Transparenzprotokoll für Provenienz
fremforge signiert für jedes Artefakt, das auf der Plattform gebaut wird, eine Provenienz-Attestierung. Eine Signatur beweist, dass die Attestierung von uns stammt. Sie beweist für sich allein aber nicht, dass wir sie seitdem nicht durch eine andere ersetzt haben: Derselbe Schlüssel würde den Ersatz genauso überzeugend signieren.
Das Transparenzprotokoll schließt diese Lücke. Jede Attestierung wird in einen
Append-only-Merkle-Baum eingetragen, der unter log.frem.sh veröffentlicht ist, und das Log signiert
regelmäßig einen Checkpoint: eine Aussage über Größe und Root-Hash des Baums zu
einem bestimmten Zeitpunkt. Weil der Baum nur wachsen kann und jeder Checkpoint nachweislich
den vorigen erweitern muss, können wir eine Attestierung nachträglich weder entfernen
noch verändern, ohne einen Checkpoint zu erzeugen, der einem bereits veröffentlichten widerspricht.
Was im Log steht und was nicht
Ein Blatt ist ein Digest, keine Attestierung. Jeder Eintrag ist der SHA-256 eines DSSE- Umschlags und nichts anderes.
Das ist Absicht, und genau das erlaubt es, das Log vollständig öffentlich zu machen. Wer seinen eigenen Umschlag hat, kann nachweisen, dass er im Log steht: die Bytes hashen, einen Inklusionsnachweis abrufen und ihn gegen einen Checkpoint prüfen. Wer deinen Umschlag nicht hat, erfährt nur, dass an irgendeinem Index ein 32-Byte-Wert protokolliert wurde. Repository- Namen, Commit-SHAs, Artefaktnamen und Build-Zeiten bleiben privat.
Die Umschläge selbst zu veröffentlichen, würde deinem Nachweis nichts hinzufügen, aber jeden Build jedes Mandanten dauerhaft aufzählbar machen, und das in einer Struktur, die konstruktionsbedingt nie etwas löschen kann.
Was es heute beweist und was nicht
Lies das, bevor du dich darauf verlässt.
Ein Checkpoint trägt die Signatur von fremforge und eine Witness-Kosignatur.
Unsere Signatur macht das Log manipulationserkennbar: Hast du einen Nachweis und schreiben wir später die Historie um, lässt sich dein Nachweis nicht mehr verifizieren, und du kannst den Widerspruch belegen.
Die Witness-Kosignatur ist das, was unsere eigene Signatur nie sein kann: eine dritte Partei,
die sich weigert, zwei widersprüchliche Checkpoints mitzusignieren. Seit dem 16. September 2026
wird jeder Checkpoint von witness.stagemole.eu kosigniert, betrieben von Mullvad VPN
AB. Sie trägt außerdem einen Zeitstempel, für den ein C2SP-Checkpoint kein Feld hat:
Ohne ihn ist ein veralteter, aber gültig signierter Checkpoint nicht von einem
aktuellen zu unterscheiden.
Ein Witness ist kein Quorum, und das sagen wir lieber offen, als das Wort „Witness" mehr leisten zu lassen, als es kann. Ein einzelner Kosignierer erhöht den Aufwand, dir einen anderen Baum zu zeigen als allen anderen; unmöglich macht er es nicht, weil er eine Absprache zwischen dem Log und seinem einzigen Witness nicht erkennen kann. Der Betreiber bezeichnet diese Instanz außerdem als Staging und nicht als Produktion.
Wissenswert, wenn du die Unabhängigkeit beurteilst: Die einzigen produktionsreifen Witnesses in der Europäischen Union, Glasklar Teknik, Mullvad VPN und Tillitis, haben eine gemeinsame Muttergesellschaft, Amagicom AB, was ihre eigenen Maintainer veröffentlichen. Weitere von ihnen hinzuzunehmen, brächte Verfügbarkeit, keine Unabhängigkeit. Wir werden diese Gruppe nicht als unabhängige Parteien bezeichnen.
Der Trust Root veröffentlicht die aktuelle Liste unter transparency_log.witnesses.
fremforge attest-verify prüft jeden Eintrag und meldet, wie viele es verifiziert hat.
Eine fehlende Kosignatur lässt die Verifikation jetzt scheitern.
Weil der Trust Root einen Witness deklariert, verlangt attest-verify mindestens eine
Kosignatur, um zu verifizieren. Ist der Witness beim Veröffentlichen nicht erreichbar, geht der
Checkpoint nur mit unserer Signatur hinaus, und deine Prüfung scheitert: Die
Witness-Prüfung meldet 0/1 verified.
Das ist das beabsichtigte Verhalten: Ein deklarierter Witness, der stillschweigend fehlt, ist genau der Fall, über den du informiert werden willst. Es bedeutet aber, dass ein gescheiterter Lauf nicht automatisch ein Beweis für Manipulation ist. Lies nach, welche Prüfung gescheitert ist, bevor du einen Schluss ziehst, und hol dir den Checkpoint über die Endpunkte selbst.
Endpunkte
| Pfad | Inhalt |
|---|---|
https://log.frem.sh/checkpoint | Der aktuelle signierte Checkpoint |
https://log.frem.sh/tile/<level>/<index> | Kacheln des Merkle-Baums |
https://log.frem.sh/tile/entries/<index> | Eintragsbündel (die protokollierten Digests) |
Die Formate sind die C2SP-Community-Standards tlog-checkpoint, signed-note und tlog-tiles, keine Erfindung von fremforge, sodass vorhandene Werkzeuge von Drittanbietern sie lesen können.
Prüfen, dass deine Attestierung protokolliert ist
Ein Befehl, und er braucht kein fremforge-Konto:
fremforge attest-verify <asset>.intoto.jsonl --human✓ envelope signatures 6/6 verify under fremforge-slsa-builder-v2
✓ checkpoint signature signed by log.frem.sh
✓ tiles hash to the checkpoint root
✓ every attestation is in the log
6/6 at leaf indices: fremforge-linux-x64@255, …
✓ append-only since last run
✓ 7/7 checks passed (computed on this machine — the server was not asked
for a verdict)Er endet mit einem Exit-Code ungleich null, wenn eine Prüfung scheitert, und passt so unverändert in CI.
attest-verify meldet in diesem Zeitfenster NOT LOGGED und endet mit
einem Exit-Code ungleich null, zu Recht, denn sie ist noch nicht da. Führe den Befehl kurz darauf erneut aus. Ist das
Artefakt älter als etwa fünfzehn Minuten und meldet weiterhin NOT LOGGED, ist das ein echter Fehler,
den du uns melden solltest.Jeder Hash und jede Signatur wird auf deinem Rechner neu berechnet. Von uns werden nur Bytes abgefragt: der Trust Root, der Checkpoint, die Kacheln. Nichts in der Ausgabe ist ein Urteil, das wir dir geliefert haben, und genau darum geht es: Ein Prüfwerkzeug, das die geprüfte Partei fragt, ob alles in Ordnung ist, hat nichts geprüft.
Eine .intoto.jsonl ist JSON Lines: ein Umschlag pro Artefakt, sodass ein Release-Bündel
einen pro Binary plus die SBOM enthält. Alle werden geprüft.
Bewahre die Zustandsdatei auf
attest-verify speichert den Baum, den es gesehen hat, in ~/.config/fremforge/tlog-state.json
(überschreibbar mit --state=<path>) und prüft beim nächsten Lauf, ob der neue Baum
diesen unverändert enthält. Das ist die Prüfung, die keine dritte Partei braucht, und
sie erkennt eine geteilte Sicht, die gezielt auf dich gerichtet ist. Führe sie also
mehr als einmal aus, von einem Ort, den du behältst, und lösche die Datei nicht, um einen
Fehler loszuwerden. Sie schreibt den gespeicherten Baum bewusst nicht fort, wenn die Prüfung
scheitert, sodass eine erkannte Umschreibung bei jedem weiteren Lauf erkannt bleibt.
Oder von Hand
Der Befehl ist eine Bequemlichkeit, keine Abhängigkeit. Wenn du auch unserem Binary
lieber nicht vertrauen willst, eine vernünftige Haltung gegenüber dem einen Werkzeug, dessen Aufgabe es ist,
uns zu misstrauen, dann kommt der folgende Weg mit nichts als curl, jq und sha256sum aus, und
die Formate sind Community-Standards, die auch tlog-tiles-Clients von Drittanbietern
lesen.
Du brauchst deinen Umschlag <asset>.intoto.jsonl, der zusammen mit dem
Artefakt ausgeliefert wird.
# 1. The log's public key, from the trust root.
curl -sSfL https://www.frem.sh/.well-known/slsa-trust-root.json -o trust-root.json
jq -r '.transparency_log.vkey' trust-root.jsonDer vkey hat die Form log.frem.sh+<keyhash>+<base64 key>. Trenne ihn nur an den
ersten beiden +: Das letzte Feld ist base64 und enthält selbst +.
# 2. The digest of YOUR envelope. This is the leaf content.
#
# ONE LINE AT A TIME, AND INCLUDING ITS TRAILING NEWLINE — that is the unit
# the log commits to. Hashing the bundle as a whole finds nothing, which
# looks exactly like "your attestation was never logged".
head -c $(( $(head -1 <asset>.intoto.jsonl | wc -c) )) <asset>.intoto.jsonl | sha256sum# 3. The current checkpoint, and the entries the log has published.
curl -sSfL https://log.frem.sh/checkpointEin Checkpoint besteht aus dem Ursprung, der Baumgröße, dem base64-kodierten Root-Hash, einer Leerzeile
und einer oder mehreren Signaturzeilen, die mit einem Geviertstrich (—) beginnen. Dein Digest
erscheint in einem der Eintragsbündel unter tile/entries/; seine Position ist sein
Blattindex, und die Kacheln unter tile/<level>/ ergeben den Inklusionsnachweis von
diesem Blatt bis zu dem Root-Hash, auf den sich der Checkpoint festlegt.
Jeder tlog-tiles-Client kann diesen Weg für dich gehen. Wenn du keinen verwenden willst, ist die nützliche Eigenschaft einfacher und trotzdem prüfenswert: Dein Digest muss erscheinen, und die Baumgröße des Checkpoints darf immer nur wachsen.
Prüfen, dass das Log die Historie nicht umgeschrieben hat
fremforge attest-verify erledigt das über mehrere Läufe hinweg für dich; siehe Bewahre die
Zustandsdatei auf oben. Von Hand:
Bewahre jeden Checkpoint auf, den du gesehen hast. Hol dir später einen neueren und bitte das Log um einen Konsistenznachweis zwischen den beiden Größen. Erweitert der neuere Baum den älteren nicht, kann der Nachweis nicht erzeugt werden, und ein Log, das ihn nicht erzeugen kann, hat die Historie umgeschrieben.
Das ist die Prüfung, die ein Witness laufend durchführt, und deshalb sind Witnesses wichtiger als jede einzelne Prüfung, die du von Hand machst.
Verhältnis zu den anderen Integritätsmechanismen
fremforge betreibt drei getrennte Dinge, die leicht zu verwechseln sind:
| Mechanismus | Deckt ab | Wo |
|---|---|---|
| Audit-Kette | Admin-Aktionen in deiner Organisation | Hash-Kette pro Mandant, WORM-verankert |
| Schlüsselloses Commit-Signieren | Git-Commits | Selbst gehosteter Fulcio + RFC3161-TSA, kein Rekor |
| Dieses Log | Build-Provenienz-Attestierungen | log.frem.sh |
Sie sind voneinander unabhängig. Insbesondere verwendet das schlüssellose Commit-Signieren weiterhin kein Transparenzprotokoll: Sein Integritätsbaustein ist der RFC3161-Zeitstempel, wie in der Sicherheitsübersicht beschrieben. Dieses Log deckt nur Provenienz- Attestierungen ab.
Souveränität
Das Log läuft auf T Cloud Public in eu-de und wird mit einem Ed25519-Schlüssel signiert, den fremforge
verwahrt. Es ist nicht Rekor und hängt weder von sigstore.dev noch von einem
in den USA betriebenen Log oder einem öffentlichen CDN außerhalb der EU ab.
Witnesses sind eine bewusste Ausnahme im Entstehen: Der Wert eines Witness liegt darin, dass er nicht wir ist, also kann ein Witness durchaus anderswo betrieben werden. Ein Witness sieht nur Checkpoints, einen Ursprung, eine Baumgröße und einen Root-Hash, nie deine Repositorys, deine Artefakte oder deine Builds. Jeder Witness, den wir hinzufügen, wird im Trust Root aufgeführt, sodass die Gruppe überprüfbar ist statt nur angenommen.