Signature de commits sans clé avec gitsign
Signez vos commits Git avec votre identité IdP, et non avec une clé SSH de longue durée. La signature de commits sans clé de fremforge repose sur les briques de Sigstore, mais chaque composant tourne sur T Cloud Public eu-de, l’autorité de certification racine réside dans un HSM FIPS 140-2 de niveau 3 en Allemagne, et vos signatures sont liées à l’IdP auquel votre organisation fremforge fait déjà confiance (Microsoft Entra, Okta, Google Workspace, Authentik, tout ce qui parle OIDC).
Chaque commit signé apparaît dans Forgejo avec la mention Verified by sigstore: <your-email> via <your-IdP>. Pas de serveur de clés. Pas de mauvaise surprise d’expiration. Plus de « ai-je bien importé cette clé sur le nouveau portable ? ».
Pourquoi s’en donner la peine (par rapport à la signature SSH)
| Signature par clé SSH | Sans clé (sigstore) | |
|---|---|---|
| Lien avec l’identité | « Correspond à une clé SSH enregistrée » | « Signé par you@org.com, attesté par Microsoft Entra » |
| Durée de vie de la clé | Permanente (rotation manuelle) | Certificat de 10 minutes, renouvelé via OIDC |
| Portable perdu = clé perdue | Vous ajoutez à nouveau la nouvelle clé partout | Vous vous connectez à votre IdP, c’est tout |
| MFA à la signature | Ce que vous avez configuré sur la clé | Ce qu’exige votre IdP (en général une MFA à chaque renouvellement) |
| Vérifiable dans une CI tierce | Difficile (appel spécifique à l’API Forgejo) | cosign verify fonctionne avec l’autorité de certification de fremforge |
Les deux méthodes de signature coexistent sur fremforge : l’administrateur de votre organisation choisit le niveau d’exigence (voir Politiques d’organisation ci-dessous). Les nouveaux développeurs devraient adopter gitsign par défaut ; les configurations existantes de signature SSH continuent de fonctionner.
Configuration (une seule fois)
1. Installez gitsign
# 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. Configurez git
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-urlRemplacez https://your-idp-issuer-url par l’URL d’émetteur OIDC configurée par votre organisation (voir le réglage URL d’émetteurs OIDC autorisées dans l’administration fremforge de votre organisation, ou demandez à son administrateur).
3. Signez votre premier commit
cd your-repo
git commit -S -m "First signed commit"Un onglet de navigateur s’ouvre, vous vous authentifiez auprès de votre IdP (une seule action si vous êtes déjà connecté), et le commit est signé. Le cache du navigateur conserve le certificat environ 10 minutes, si bien que les commits suivants de la même session ne redemandent rien.
4. Vérifiez que cela a fonctionné
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)Dans l’interface web de fremforge, votre commit affiche le badge Verified by sigstore à côté de son hash.
Vous préférez une clé GPG ?
fremforge vérifie aussi les commits signés avec votre propre clé GPG. Créez-en une, indiquez à Git de l’utiliser et exportez sa partie publique :
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>Collez le bloc qui commence par -----BEGIN PGP PUBLIC KEY BLOCK----- dans Paramètres utilisateur → Clés SSH / GPG → Gérer les clés GPG → Ajouter une clé. L’adresse e-mail de la clé doit être une adresse vérifiée de votre compte ; vos commits signés apparaissent alors comme Verified. La signature sans clé décrite plus haut fait la même chose sans clé à entretenir, c’est pourquoi c’est la voie recommandée. Ne combinez pas les deux : le réglage gpg.format x509 de l’étape 2 est réservé à gitsign.
Signature en CI / sans navigateur
Si vous signez depuis la CI ou depuis une machine sans navigateur :
# 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"Comment obtenir le jeton selon l’IdP :
- GitHub Actions → autorisation intégrée
id-token: write - Identité de charge de travail Microsoft Entra →
az account get-access-token --resource <fulcio-audience> - Authentik → parcours OAuth par code d’appareil via le mode sans navigateur de
gitsign - Tout le reste → n’importe quel jeton conforme à OIDC fonctionne, du moment que l’émetteur figure dans la liste autorisée de votre organisation
Politiques d’organisation
Deux réglages de /<your-org>/_admin/auth-policy déterminent le comportement de la signature sans clé :
- URL d’émetteurs OIDC autorisées : doit inclure l’URL d’émetteur de votre IdP. Le hook pre-receive lit l’extension
OIDCIssuerdu certificat et refuse tout commit dont l’émetteur ne figure pas dans cette liste. Liste vide = signature sigstore désactivée pour cette organisation. - Mode strict : lorsqu’il est activé, seuls les commits signés par sigstore sont acceptés sur les branches où Require signed commits est activé. Les commits signés par SSH sont refusés. Ne l’activez pas avant que tous vos développeurs aient migré.
Dépannage
gitsign: oidc issuer not allowed by Fulcio : l’URL d’émetteur de votre IdP est correcte, mais le Fulcio de la plateforme ne lui fait pas encore confiance. Administrateur de l’organisation : ouvrez /<slug>/_admin/auth-policy et ajoutez l’URL d’émetteur dans URL d’émetteurs OIDC autorisées. fremforge applique la modification automatiquement (~30 s) ; aucun ticket auprès de l’opérateur n’est nécessaire.
gitsign: cert expired before push completed : vous avez exécuté un script long entre l’émission du certificat et le push. Le certificat est valable 10 minutes. Lancez git commit --amend --no-edit -S pour signer à nouveau avec un certificat neuf avant de pousser.
Badge Verified absent d’un commit signé : consultez /<your-org>/<repo>/commit/<sha>/status ; le statut fremforge-sigstore-verified apparaît comme un contrôle à côté des autres contrôles CI. S’il indique « failure », cliquez dessus pour en connaître la raison. S’il est totalement absent, le hook pre-receive ne s’est pas déclenché : soit le commit est trop ancien (poussé avant l’activation de la politique), soit votre push a emprunté un chemin inattendu. Contactez le support en indiquant le SHA du commit.
Le badge « Verified » de Forgejo indique « unsigned » alors que git verify-commit fonctionne : le vérificateur natif de Forgejo ne comprend pas encore les signatures sigstore ; c’est pourquoi nous utilisons à la place le badge de statut du commit. Le statut fremforge-sigstore-verified fait foi. (Prise en charge en amont suivie dans gitea#34361.)
Comment cela fonctionne en coulisses
gitsignouvre le parcours de connexion OIDC de votre IdP.- Votre IdP émet un jeton d’identité de courte durée qui atteste votre identité.
gitsignenvoie ce jeton à l’autorité de certification Fulcio de fremforge (sign.frem.sh).- Fulcio valide le jeton et émet un certificat X.509 de 10 minutes, avec votre e-mail dans le SAN et l’URL d’émetteur de l’IdP dans l’extension
OIDCIssuer. La clé de signature réside dans un HSM T Cloud Public DEW (FIPS 140-2 niveau 3, juridiction allemande). gitsignsigne le contenu du commit avec la clé privée du certificat (conservée uniquement dans la mémoire locale de votre navigateur pendant la durée de vie du certificat).- La TSA de fremforge (
tsa.frem.sh) signe un horodatage de confiance RFC 3161 qui atteste que « le certificat était valide à cette seconde précise » : c’est ce qui permet la vérification même après l’expiration du certificat. - La signature, le certificat et l’horodatage sont intégrés dans l’en-tête
gpgsigdu commit (format CMS/PKCS7). - Vous poussez. Le hook pre-receive de fremforge vérifie la chaîne du certificat jusqu’à notre racine Fulcio, l’horodatage jusqu’à notre racine TSA, et l’émetteur OIDC par rapport à la liste autorisée de votre organisation.
- L’API de statut des commits de Forgejo enregistre le résultat.
La vérification ne nécessite que le certificat racine Fulcio et la racine TSA : aucun appel réseau pendant la vérification. Une indisponibilité de l’autorité de certification n’affecte pas les commits déjà signés, seulement les nouvelles tentatives de signature.
Vérifier de façon indépendante, hors de fremforge
Si vous voulez qu’une CI tierce (ou simplement votre portable) vérifie les commits signés par fremforge sans faire confiance à fremforge :
# 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>Le format de signature est le même que pour n’importe quelle autre signature de l’écosystème Sigstore : il fonctionne avec cosign verify-blob et le reste de l’outillage OpenSSF de signature de commits et de blobs. (Remarque : slsa-verifier vérifie la provenance de build des artefacts, pas les signatures de commits git ; il ne s’applique donc pas ici. La provenance de build de fremforge suit un chemin distinct, signé en Ed25519 : voir Provenance SLSA.)