Le VPS de production tire le dépôt via une deploy key — bien. Sauf qu'elle a été générée sur le portable du directeur technique, copiée dans /root/.ssh et réutilisée pour staging et production. Quand le staging est compromis lors d'un plugin WordPress vulnérable, l'attaquant clone aussi le dépôt privé de l'API — même clé, accès lecture sur tout le monorepo attaché.
Les clés de déploiement sont le passeport entre votre hébergeur et Git. Mal découpées, elles transforment un incident applicatif en fuite de propriété intellectuelle.
Deploy key SSH : périmètre minimal
Sur GitHub ou GitLab : deploy key par dépôt, en lecture seule pour un serveur qui ne fait que tirer le code.
| Approche | Avantage | Risque |
|---|---|---|
| Deploy key read-only | Accès limité à un repo | Clé dupliquée multi-env |
| PAT machine user | API riche | Scope trop large, pas de rotation |
| OAuth app | Centralisé | Complexité, audit |
Créez un utilisateur Linux deploy sans shell login (/usr/sbin/nologin), avec ForceCommand si vous devez restreindre à git-shell.
Une clé sur le serveur de production vaut ce que vaut ce serveur — traitez-la comme un secret de premier niveau.
CI vs runtime : deux identités distinctes
Le pipeline CI (GitHub Actions, GitLab CI) utilise un token avec scopes read_repository ou une deploy key write uniquement si vous automatisez tags et releases — jamais avec droits admin sur l'organisation.
Le serveur de production ne fait que tirer le code. Le CI construit et pousse l'artefact (image, archive) ; le serveur ne clone pas forcément à chaque déploiement si vous livrez des images immuables.
Séparer identifiants de build et identifiants de déploiement limite la chaîne d'attaque.
Rotation, audit et inventaire
Tenez un registre : clé → dépôt → environnement → date de création → prochaine rotation. Automatisez une alerte à 90 jours.
Procédure type : générer une nouvelle paire ed25519, ajouter la clé publique sur l'hébergeur Git en coexistence courte, valider le déploiement sur staging puis production, révoquer l'ancienne. Après incident : révoquer immédiatement, pas « lundi prochain ».
Hébergeurs et accès git alternatifs
Sur mutualisé sans SSH git : déployez via FTP ou rsync depuis le CI — pas de clé longue durée sur l'hébergement partagé. Sur VPS et bare metal : deploy key standard.
Certaines plateformes PaaS (Clever Cloud, etc.) utilisent des webhooks — pas de clé sur la machine ; vérifiez qui peut déclencher un déploiement.
Erreurs fréquentes
Clé privée commitée dans le dépôt — scannez l'historique git. StrictHostKeyChecking no facilite les attaques MITM : épinglez known_hosts. Submodule privé sans deploy key dédiée : le clone parent réussit, le submodule échoue ou force une clé trop large. Token personnel du lead réutilisé en CI et sur le serveur : une seule fuite compromet build et production.
Le sommet : read-only qui lit trop
Automatiser sans bloquer signifie identités machine courtes, périmètre minimal, rotation documentée — pas une clé immortelle dans root.
Décider et avancer sans angle mort
Créez une deploy key par dépôt et par environnement, un utilisateur deploy dédié, des identifiants CI séparés, une rotation trimestrielle et un audit des known_hosts. Comparez VPS et PaaS avec déploiement sécurisé via l'annuaire et le comparateur. Les guides détaillent les pipelines.
Faites un audit immédiat : listez les clés Git actives et les dépôts accessibles — supprimez les orphelines.
Questions fréquentes
Deploy key ou token CI ?
Deploy key en lecture seule par dépôt pour le serveur qui tire le code ; token CI à scopes minimaux pour les appels API.
Pourquoi interdire write sur une deploy key ?
Un serveur compromis avec droits d'écriture expose la supply chain ; réservez le pull-only en production.
Comment rotationner sans couper la prod ?
Coexistence courte de deux clés, validation sur staging, puis révocation de l'ancienne clé.
Un seul utilisateur git partagé sur le serveur ?
Anti-pattern — préférez un utilisateur deploy dédié et une clé par environnement.
Une deploy key propre ne peut cloner qu'un dépôt — pas votre matinée après un staging compromis.