Sleutelloos commits ondertekenen met gitsign
Onderteken Git-commits met je IdP-identiteit, niet met een langlevende SSH-sleutel. Het sleutelloos ondertekenen van commits in fremforge gebruikt de bouwstenen van Sigstore, maar elk onderdeel draait op T Cloud Public eu-de, de root-CA staat in een HSM volgens FIPS 140-2 Level 3 in Duitsland, en je handtekeningen zijn gebonden aan de IdP die je fremforge-organisatie al vertrouwt (Microsoft Entra, Okta, Google Workspace, Authentik, alles wat OIDC spreekt).
Elke ondertekende commit verschijnt in Forgejo als Verified by sigstore: <your-email> via <your-IdP>. Geen keyserver. Geen verrassingen met verlopen sleutels. Geen “heb ik die sleutel wel op de nieuwe laptop geïmporteerd?”.
Waarom (in plaats van ondertekenen met SSH)
| Ondertekenen met een SSH-sleutel | Sleutelloos (sigstore) | |
|---|---|---|
| Binding aan identiteit | “Komt overeen met een geregistreerde SSH-sleutel” | “Ondertekend door you@org.com, bevestigd door Microsoft Entra” |
| Levensduur van de sleutel | Permanent (roteren = handwerk) | Certificaat van 10 minuten, vernieuwd via OIDC |
| Laptop kwijt = sleutel kwijt | Je voegt overal de nieuwe sleutel toe | Je logt in bij je IdP, klaar |
| MFA bij ondertekenen | Wat je op de sleutel hebt ingesteld | Wat je IdP vereist (meestal MFA bij elke vernieuwing) |
| Controleerbaar in CI van derden | Lastig (eigen aanroep van de Forgejo-API) | cosign verify werkt tegen de CA van fremforge |
Beide ondertekeningsmethoden bestaan naast elkaar in fremforge; de beheerder van je organisatie kiest hoe streng het is (zie Organisatiebeleid hieronder). Nieuwe ontwikkelaars gebruiken standaard het best gitsign; bestaande inrichtingen met SSH-ondertekening blijven werken.
Inrichten (eenmalig)
1. gitsign installeren
# macOS (Homebrew)
brew install sigstore/tap/gitsign
# Linux (binary)
curl -sLO https://github.com/sigstore/gitsign/releases/latest/download/gitsign-linux-amd64
chmod +x gitsign-linux-amd64 && sudo mv gitsign-linux-amd64 /usr/local/bin/gitsign
# Verify
gitsign --version2. Git configureren
git config --global gpg.x509.program gitsign
git config --global gpg.format x509
git config --global commit.gpgsign true
# Point gitsign at fremforge's private Fulcio + TSA (not the public Sigstore).
git config --global gitsign.fulcio https://sign.frem.sh
git config --global gitsign.timestamp-server-url https://tsa.frem.sh
git config --global gitsign.rekor "" # explicitly empty — fremforge uses TSA-only, no transparency log
git config --global gitsign.connectorID https://your-idp-issuer-urlVervang https://your-idp-issuer-url door de URL van de OIDC-uitgever die je organisatie heeft geconfigureerd (zie het onderdeel Organisatiebeleid → Toegestane OIDC-uitgever-URL’s in de beheeromgeving van fremforge, of vraag het de beheerder van je organisatie).
3. Je eerste commit ondertekenen
cd your-repo
git commit -S -m "First signed commit"Er opent een browsertabblad, je authenticeert bij je IdP (één tik als je al bent ingelogd) en de commit wordt ondertekend. De browsercache bewaart het certificaat ongeveer 10 minuten, zodat volgende commits in dezelfde sessie niet opnieuw om bevestiging vragen.
4. Controleren of het werkte
git verify-commit HEAD
# tlog index: <n>
# Good signature from [you@yourorg.com](you@yourorg.com)
# Validated Git signature: true
# Validated Rekor entry: true (or "skipped" — fremforge doesn't run Rekor)In de webinterface van fremforge toont je commit het label Verified by sigstore naast de commit-hash.
Liever een GPG-sleutel?
fremforge verifieert ook commits die zijn ondertekend met je eigen GPG-sleutel. Maak er een aan, laat Git hem gebruiken en exporteer het publieke deel:
gpg --full-generate-key
gpg --list-secret-keys --keyid-format=long # the key ID follows "sec ed25519/"
git config --global user.signingkey <key-id>
git config --global commit.gpgsign true
gpg --armor --export <key-id>Plak het blok dat begint met -----BEGIN PGP PUBLIC KEY BLOCK----- onder Instellingen → SSH / GPG sleutels → Beheer GPG sleutels → Sleutel toevoegen. Het e-mailadres van de sleutel moet een geverifieerd adres op je account zijn; je ondertekende commits verschijnen dan als Geverifieerd. Sleutelloos ondertekenen hierboven doet hetzelfde zonder sleutel om op te passen, en daarom is dat de aanbevolen weg. Combineer de twee niet: de instelling gpg.format x509 uit stap 2 is alleen voor gitsign.
Ondertekenen in CI of zonder browser
Onderteken je vanuit CI of op een machine zonder browser:
# Get an OIDC token from your IdP (different per IdP — see below)
export SIGSTORE_ID_TOKEN="<bearer-token-from-your-idp>"
# Then sign as usual
git commit -S -m "Signed from CI"Recepten per IdP om een token op te halen:
- GitHub Actions → de ingebouwde permissie
id-token: write - Microsoft Entra workload identity →
az account get-access-token --resource <fulcio-audience> - Authentik → OAuth-device-code-stroom via de headless modus van
gitsign - Al het andere → elk OIDC-conform token werkt, zolang de uitgever op de allowlist van je organisatie staat
Organisatiebeleid
Twee instellingen op /<your-org>/_admin/auth-policy bepalen hoe sleutelloos ondertekenen werkt:
- Toegestane OIDC-uitgever-URL’s: moet de uitgever-URL van je IdP bevatten. De pre-receive-hook leest de extensie
OIDCIssuervan het certificaat en weigert elke commit waarvan de uitgever niet in deze lijst staat. Lege lijst = ondertekenen met sigstore uitgeschakeld voor deze organisatie. - Strikte modus: als die aanstaat, worden op branches waarvoor Ondertekende commits vereisen is ingeschakeld alleen met sigstore ondertekende commits geaccepteerd. Met SSH ondertekende commits worden geweigerd. Zet dit pas aan als al je ontwikkelaars zijn overgestapt.
Probleemoplossing
gitsign: oidc issuer not allowed by Fulcio: de uitgever-URL van je IdP klopt, maar de Fulcio van het platform vertrouwt hem nog niet. Beheerder van de organisatie: open /<slug>/_admin/auth-policy en voeg de uitgever-URL toe aan Toegestane OIDC-uitgever-URL’s. fremforge past de wijziging automatisch toe (~30 s); er is geen ticket bij de operator nodig.
gitsign: cert expired before push completed: je hebt tussen het aanmaken van het certificaat en de push een langlopend script gedraaid. Het certificaat geldt 10 minuten. Voer git commit --amend --no-edit -S uit om vóór het pushen opnieuw te ondertekenen met een vers certificaat.
Het label Verified ontbreekt bij een ondertekende commit: kijk op /<your-org>/<repo>/commit/<sha>/status; de status fremforge-sigstore-verified verschijnt als check naast de andere CI-checks. Staat die op “failure”, klik er dan op voor de reden. Ontbreekt hij helemaal, dan is de pre-receive-hook niet uitgevoerd: de commit is te oud (gepusht voordat het beleid werd ingeschakeld) of je push is via een onverwachte route gegaan. Neem contact op met support en vermeld de SHA van de commit.
Het eigen label “Verified” van Forgejo zegt “unsigned”, maar git verify-commit werkt: de ingebouwde verificatie van Forgejo begrijpt sigstore-handtekeningen nog niet; daarom gebruiken we in plaats daarvan het label van de commitstatus. De status fremforge-sigstore-verified is leidend. (We volgen gitea#34361 voor ondersteuning upstream.)
Hoe het onder de motorkap werkt
gitsignopent de OIDC-inlogstroom van je IdP.- Je IdP geeft een kortlevend ID-token uit dat je identiteit bevestigt.
gitsignstuurt het token naar de Fulcio-CA van fremforge (sign.frem.sh).- Fulcio valideert het token en maakt een X.509-certificaat van 10 minuten aan, met je e-mailadres in de SAN en de uitgever-URL van de IdP in de extensie
OIDCIssuer. De ondertekeningssleutel staat in een T Cloud Public DEW-HSM (FIPS 140-2 Level 3, Duitse jurisdictie). gitsignondertekent de inhoud van de commit met de privésleutel van het certificaat (die alleen tijdens de levensduur van het certificaat in het geheugen van je lokale browser staat).- De TSA van fremforge (
tsa.frem.sh) ondertekent een vertrouwde tijdstempel volgens RFC 3161 die vastlegt dat het certificaat op precies die seconde geldig was. Daardoor werkt verificatie ook nadat het certificaat is verlopen. - De handtekening, het certificaat en de tijdstempel worden ingebed in de
gpgsig-header van de commit (CMS/PKCS7-formaat). - Je pusht. De pre-receive-hook van fremforge controleert de certificaatketen → onze Fulcio-root, de tijdstempel → onze TSA-root, en de OIDC-uitgever tegen de toegestane lijst van je organisatie.
- De commitstatus-API van Forgejo legt het resultaat vast.
Voor verificatie zijn alleen het Fulcio-rootcertificaat en de TSA-root nodig; tijdens het verifiëren zijn er geen netwerkaanroepen. Uitval van de CA heeft geen invloed op commits die al zijn ondertekend, alleen op nieuwe ondertekenpogingen.
Onafhankelijk verifiëren buiten fremforge
Wil je dat CI van derden (of gewoon je laptop) door fremforge ondertekende commits verifieert zonder fremforge te vertrouwen:
# Fetch fremforge's CA root + TSA root (publicly served, integrity via TLS)
curl -sf https://docs.frem.sh/_pki/fulcio-root.pem > /tmp/fremforge-fulcio.pem
curl -sf https://docs.frem.sh/_pki/tsa-root.pem > /tmp/fremforge-tsa.pem
# Use cosign to verify a specific commit
cosign verify-blob \
--certificate-chain /tmp/fremforge-fulcio.pem \
--timestamp-certificate-chain /tmp/fremforge-tsa.pem \
--certificate-identity "you@yourorg.com" \
--certificate-oidc-issuer "https://your-idp-issuer" \
<commit-bytes>Hetzelfde handtekeningformaat als elke andere handtekening uit het Sigstore-ecosysteem: werkt met cosign verify-blob en de rest van de OpenSSF-tooling voor het ondertekenen van commits en blobs. (Let op: slsa-verifier verifieert buildherkomst van artefacten, geen handtekeningen op git-commits, en is hier dus niet van toepassing. De buildherkomst van fremforge is een aparte route met Ed25519-handtekeningen; zie SLSA-herkomst.)