Transparenslog for provenance
fremforge signerer en provenance-attestation for hvert artefakt, der bygges på platformen. En signatur beviser, at attestationen kom fra os. Den beviser ikke i sig selv, at vi ikke siden har erstattet den med en anden: den samme nøgle ville signere erstatningen lige så overbevisende.
Det hul lukker transparensloggen. Hver attestation føjes til et Merkle-træ, der
kun kan tilføjes til, og som udgives på log.frem.sh, og loggen signerer med jævne
mellemrum et checkpoint: en erklæring om træets størrelse og rod-hash på et
givet tidspunkt. Fordi træet kun kan vokse, og hvert checkpoint beviseligt skal
udvide det forrige, kan vi ikke fjerne eller ændre en attestation bagefter uden
at lave et checkpoint, der modsiger et allerede udgivet.
Hvad der er i loggen, og hvad der ikke er
Et blad er et digest, ikke en attestation. Hver post er SHA-256 af en DSSE-konvolut og intet andet.
Det er bevidst, og det er det, der gør, at loggen kan være helt offentlig. Har du din egen konvolut, kan du bevise, at den er i loggen: hash bytene, hent et inklusionsbevis, og kontrollér det mod et checkpoint. Alle, der ikke har din konvolut, får kun at vide, at en værdi på 32 bytes blev logget ved et bestemt indeks. Repository-navne, commit-SHA’er, artefaktnavne og byggetidspunkter forbliver private.
At udgive selve konvolutterne ville ikke tilføje noget til dit bevis, men ville gøre hvert build hos hver lejer permanent opregneligt, i en struktur, der per konstruktion aldrig kan slette noget.
Hvad den beviser i dag, og hvad den ikke beviser
Læs dette, før du stoler på den.
Et checkpoint har fremforges signatur og én medsignatur fra et vidne.
Vores signatur gør loggen manipulationsevident: har du et bevis, og omskriver vi senere historikken, holder dit bevis op med at verificere, og du kan påvise modsigelsen.
Vidnets medsignatur er det, vores egen signatur aldrig kan være: en tredjepart,
der nægter at medsignere to inkonsistente checkpoints. Siden 16. september 2026
er hvert checkpoint medsigneret af witness.stagemole.eu, som drives af Mullvad VPN
AB. Den indeholder også et tidsstempel, som et C2SP-checkpoint ikke har et felt
til: uden det kan et forældet, men gyldigt signeret checkpoint ikke skelnes fra et
aktuelt.
Ét vidne er ikke et quorum, og det vil vi hellere sige, end lade ordet “vidne” bære mere, end det kan. En enkelt medsignatar gør det dyrere at vise dig et andet træ end alle andre; det gør det ikke umuligt, fordi den ikke kan opdage samarbejde mellem loggen og dens eneste vidne. Operatøren beskriver desuden denne instans som staging og ikke produktion.
Værd at vide, hvis du vurderer uafhængighed: de eneste vidner i produktionskvalitet i EU, Glasklar Teknik, Mullvad VPN og Tillitis, har samme moderselskab, Amagicom AB, hvilket deres egne vedligeholdere oplyser. Flere af dem ville give tilgængelighed, ikke uafhængighed. Vi vil ikke beskrive den gruppe som uafhængige parter.
Tillidsroden udgiver den aktuelle liste i transparency_log.witnesses.
fremforge attest-verify kontrollerer hver post og rapporterer, hvor mange den
verificerede.
En manglende medsignatur får nu verifikationen til at fejle.
Fordi tillidsroden erklærer et vidne, kræver attest-verify mindst én medsignatur
for at verificere. Kan vidnet ikke nås, når vi udgiver, går checkpointet ud med kun
vores signatur, og din kontrol fejler: vidnekontrollen rapporterer
0/1 verified.
Det er den tilsigtede adfærd: et erklæret vidne, der stille er fraværende, er netop det tilfælde, du vil have besked om. Men det betyder, at en fejlet kørsel ikke automatisk er bevis for manipulation. Læs, hvilken kontrol der fejlede, før du drager en konklusion, og se Endpoints for selv at hente checkpointet.
Endpoints
| Sti | Indhold |
|---|---|
https://log.frem.sh/checkpoint | Det aktuelle signerede checkpoint |
https://log.frem.sh/tile/<level>/<index> | Tiles fra Merkle-træet |
https://log.frem.sh/tile/entries/<index> | Postbundter (de loggede digests) |
Formaterne er C2SP-fællesskabsstandarderne tlog-checkpoint, signed-note og tlog-tiles, ikke en fremforge-opfindelse, så eksisterende tredjepartsværktøjer kan læse dem.
Verificér, at din attestation er logget
Én kommando, og den kræver ingen 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)Den afslutter med en værdi forskellig fra nul, hvis en kontrol fejler, så den kan sættes direkte ind i CI.
attest-verify rapporterer NOT LOGGED og
afslutter med en værdi forskellig fra nul i det vindue, og med rette, for den er der
ikke endnu. Kør den igen lidt senere. Er artefaktet ældre end cirka femten minutter
og rapporterer stadig NOT LOGGED, er det en reel fejl, som du bør tage op med os.Hver hash og signatur genberegnes på din maskine. Vi bliver kun bedt om bytes: tillidsroden, checkpointet, tiles. Intet i outputtet er en dom, vi har givet dig, og det er netop pointen, for et verifikationsværktøj, der spørger den part, der verificeres, om alt er i orden, har ikke verificeret noget.
En .intoto.jsonl er JSON Lines: én konvolut pr. artefakt, så et release-bundt har
én pr. binær plus SBOM’en. Alle kontrolleres.
Behold tilstandsfilen
attest-verify registrerer det træ, den så, i ~/.config/fremforge/tlog-state.json
(kan tilsidesættes med --state=<path>), og ved næste kørsel kontrollerer den, at det
nye træ stadig indeholder det uændret. Det er den kontrol, der ikke kræver nogen
tredjepart, og det er den, der fanger et opdelt billede rettet specifikt mod dig.
Kør den derfor mere end én gang, fra et sted, du beholder, og slet ikke filen for at
fjerne en fejl. Den flytter bevidst ikke det registrerede træ frem, når kontrollen
fejler, så en opdaget omskrivning forbliver opdaget ved hver efterfølgende kørsel.
Eller gør det i hånden
Kommandoen er en bekvemmelighed, ikke en afhængighed. Vil du heller ikke stole på
vores binær, hvilket er et rimeligt standpunkt over for netop det værktøj, hvis
opgave er at mistro os, bruger gennemgangen nedenfor kun curl, jq og sha256sum,
og formaterne er fællesskabsstandarder, som tlog-tiles-klienter fra tredjepart også
læser.
Du skal bruge din <asset>.intoto.jsonl-konvolut, som leveres sammen med
artefaktet.
# 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.jsonvkey’en har formen log.frem.sh+<keyhash>+<base64 key>. Del den kun ved de to
første +: det sidste felt er base64 og indeholder selv +.
# 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/checkpointEt checkpoint består af oprindelsen, træets størrelse, rod-hashen i base64, en tom
linje og en eller flere signaturlinjer, der begynder med en lang tankestreg (—).
Dit digest optræder i et af postbundterne under tile/entries/; dets position er
dets bladindeks, og tiles under tile/<level>/ giver inklusionsbeviset fra det blad
til den rod-hash, checkpointet forpligter sig til.
Enhver tlog-tiles-klient kan lave denne gennemgang for dig. Vil du helst ikke køre en, er den nyttige egenskab enklere og stadig værd at kontrollere: dit digest skal optræde, og checkpointets træstørrelse må kun vokse.
Verificér, at loggen ikke har omskrevet historikken
fremforge attest-verify gør det for dig på tværs af kørsler; se Behold
tilstandsfilen ovenfor. I hånden:
Gem alle checkpoints, du har set. Hent senere et nyere, og bed loggen om et konsistensbevis mellem de to størrelser. Udvider det nyere træ ikke det ældre, kan beviset ikke laves, og en log, der ikke kan lave det, har omskrevet historikken.
Det er den kontrol, et vidne udfører løbende, og derfor betyder vidner mere end nogen enkelt verifikation, du laver i hånden.
Forholdet til de andre integritetsmekanismer
fremforge kører tre separate ting, som er lette at forveksle:
| Mekanisme | Dækker | Hvor |
|---|---|---|
| Revisionskæde | Administrative handlinger i din organisation | Hashkæde pr. lejer, forankret i WORM |
| Nøglefri commit-signering | Git-commits | Selvhostet Fulcio + RFC3161-TSA, ingen Rekor |
| Denne log | Build-provenance-attestationer | log.frem.sh |
De er uafhængige. Især bruger nøglefri commit-signering stadig ingen transparenslog: dens integritetsprimitiv er RFC3161-tidsstemplet, som beskrevet i sikkerhedsoversigten. Denne log dækker kun provenance-attestationer.
Suverænitet
Loggen kører på T Cloud Public i eu-de og signeres med en Ed25519-nøgle, som
fremforge har. Den er ikke Rekor og afhænger ikke af sigstore.dev, nogen log drevet
fra USA eller et offentligt CDN uden for EU.
Vidner er en bevidst undtagelse under opbygning: værdien af et vidne er, at det ikke er os, så et vidne kan sagtens drives et andet sted. Et vidne ser kun checkpoints, dvs. en oprindelse, en træstørrelse og en rod-hash, aldrig dine repositorier, dine artefakter eller dine builds. Ethvert vidne, vi tilføjer, bliver opført i tillidsroden, så gruppen kan revideres i stedet for at blive taget for givet.