Signature de code dans GitHub Actions avec Certum SimplySign
ssign tourne sur une machine Linux et y signe les binaires Windows : pas de machine Windows, pas de SimplySign Desktop, pas de conteneur. L'e-mail du compte et la graine TOTP viennent de secrets d'environnement.
Un workflow de signature
name: Sign
on:
workflow_dispatch: # manuel uniquement — chaque exécution signe réellement
jobs:
sign:
runs-on: ubuntu-latest
environment: signing # ← environnement protégé ; voir la section suivante
steps:
- uses: actions/checkout@v4
- run: cargo install ssign
- run: ssign dist/*.exe
env:
CERTUM_EMAIL: ${{ secrets.CERTUM_EMAIL }}
CERTUM_OTP: ${{ secrets.CERTUM_OTP }}
- uses: actions/upload-artifact@v4
with: { name: signed, path: dist/ }
CERTUM_OTP contient votre graine TOTP, le secret à longue durée qui permet de signer
en votre nom. Stockez-la comme décrit ci-dessous, pas comme un simple secret de dépôt.
Exiger l'accord du propriétaire pour chaque signature
Signer engage votre certificat et, mal géré, peut exposer la graine. Verrouillez la signature derrière un Environment GitHub, pour que le propriétaire du dépôt approuve chaque exécution avant même que le job ne puisse lire les secrets :
- Settings → Environments → New environment, nommez-le
signing. - Ajoutez une règle Deployment protection rule → Required reviewers, et ajoutez-vous (le propriétaire). Tout job visant cet environnement se met en pause en attendant votre approbation.
- Stockez
CERTUM_EMAILetCERTUM_OTPcomme secrets d'environnement designing(pas des secrets de dépôt). Ils ne sont lisibles que dans une exécution approuvée d'un job qui déclareenvironment: signing. - Dans le workflow, le job de signature déclare
environment: signing, comme ci-dessus.
Résultat : une pull request, même malveillante, ne peut pas déclencher une signature ni lire la
graine ; chaque exécution attend le clic du propriétaire. Gardez aussi le job de signature sur
workflow_dispatch ou sur des pushes de branches protégées, jamais sur
pull_request depuis un fork.
Dans un pipeline de publication
Faites de la signature un job du même workflow que la compilation et la publication, verrouillé
par environment: signing, et que le job de publication liste dans needs:. Un tag devient
alors compilation → approbation → version signée. Ne comptez pas sur un workflow séparé déclenché par
release: published : une release créée par le GITHUB_TOKEN intégré ne déclenche
pas d'autre workflow.
Un exemple réel : ssign signe sa propre version Windows
Le workflow de publication de ssign fait exactement cela. À chaque tag de version, un job sur
ubuntu-latest reprend le binaire Linux ssign compilé plus tôt dans la même exécution, attend
l'approbation via l'environnement signing, signe ssign.exe et ssign_pkcs11.dll
pour Windows avec une seule connexion Certum, puis contrôle les deux avec osslsigncode verify. Le job de
publication l'attend. Extrait :
sign-windows:
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
environment: signing
steps:
# …download the Linux ssign and the Windows artifacts built earlier in the run…
- name: Sign the Windows binary + module with ssign (via Certum)
env:
CERTUM_EMAIL: ${{ secrets.CERTUM_EMAIL }}
CERTUM_OTP: ${{ secrets.CERTUM_OTP }}
run: |
unzip -o dl/ssign-windows-x86_64.zip -d dl
unzip -o dl/ssign-pkcs11-windows-x86_64.zip -d dl
# One Certum login signs both the CLI and the module.
ssign --verbose \
-n "ssign" -u "https://github.com/${{ github.repository }}" \
dl/ssign.exe dl/ssign_pkcs11.dll
release:
needs: [build, sign-windows, sign-apple]
Le fichier complet : .github/workflows/ci.yml.
Plusieurs fichiers, une connexion
Passez tous les fichiers au même appel de ssign, comme ci-dessus : il se connecte une seule fois pour
tout le lot. Si une étape suivante du même job signe d'autres formats avec le module
PKCS#11, le module réutilise la session en cache au lieu de se reconnecter (voir
le cache de session).