Sécurité
Les mesures de sécurité de l'infrastructure, couche par couche. L'audit complet de l'application est dans la section Cybersécurité.
Les machines
| Mesure | Effet |
|---|---|
| Shielded VM (démarrage sécurisé, vTPM, contrôle d'intégrité) | Un système modifié au démarrage est détecté |
Compte de service tm-nodes sans aucun rôle IAM | Même si une VM était compromise, elle ne pourrait rien modifier dans le projet Google Cloud. Le compte par défaut, lui, a le rôle Éditeur sur tout le projet. |
| Deux VM séparées | Les builds, qui exécutent du code tiers avec le socket Docker, n'ont aucun accès à la production |
| Ubuntu 24.04 LTS | Correctifs de sécurité maintenus |
Le réseau
| Mesure | Où | Effet |
|---|---|---|
| Pare-feu Google Cloud | devant les VM | 80 et 443 ouverts uniquement sur tm-prod (tag web), règle RDP supprimée |
| UFW, « tout refuser » par défaut | sur chaque VM | Seuls les ports autorisés sont joignables |
Un seul conteneur publié sur tm-prod | Traefik | Docker contourne UFW : en ne publiant que Traefik, rien d'autre n'est exposé |
| Jenkins lié à l'IP interne | tm-tooling | Pas d'écoute sur l'IP publique, même si UFW était contourné |
Réseau Docker internal | tm-prod | La base n'a aucun accès à l'extérieur et n'est joignable que par l'API |
| Échanges entre machines par le réseau interne | les deux | Le déploiement SSH ne passe pas par internet |
Le chiffrement
| Mesure | Effet |
|---|---|
| HTTPS partout, certificats Let's Encrypt | Rien ne circule en clair entre les utilisateurs et les serveurs |
| Redirection automatique de 80 vers 443 | Impossible de rester en HTTP |
| Secrets chiffrés avec Ansible Vault | Rien de sensible en clair dans Git |
Les accès
| Mesure | Effet |
|---|---|
| SSH par clé uniquement | Pas de mot de passe à deviner |
host_key_checking = True dans Ansible | Refuse une machine qui aurait été remplacée |
Utilisateur deploy dédié | Jenkins ne se connecte pas avec le compte d'administration |
deploy n'accepte que la clé de Jenkins | Aucune autre clé ne peut l'utiliser |
Jeton GHCR en lecture seule sur tm-prod | La production peut télécharger les images, pas en publier |
| Jenkins : un seul compte, pas d'inscription | Personne ne peut créer de compte |
La chaîne de livraison
| Mesure | Effet |
|---|---|
| Scan Trivy à chaque build | Une faille critique connue dans les paquets système bloque le déploiement |
| Code copié dans le conteneur de test | Le code exécuté pendant les tests n'a jamais accès au socket Docker ni à la clé de déploiement |
| Images en plusieurs étapes | Ni code source, ni compilateur, ni dépendances de build en production |
Frontend avec nginx-unprivileged | nginx ne tourne pas en root |
Backend avec l'utilisateur nobody et apt-get upgrade | L'API ne tourne pas en root, avec les correctifs système à jour |
server_tokens off dans nginx | La version de nginx n'est pas annoncée |
Dashboard Traefik désactivé, pas d'accès à docker.sock | Une faille dans Traefik ne donne pas la main sur Docker |
Les secrets
| Mesure | Effet |
|---|---|
.env et clés en 0600 | Lisibles par leur seul propriétaire |
no_log: true | Absents des journaux d'Ansible |
| Clé SSH montée en secret Docker | Jamais dans une variable d'environnement visible par docker inspect |
withCredentials et --password-stdin | Jetons masqués dans les journaux Jenkins, absents de la liste des processus |
docker logout après chaque push | Pas de session GHCR qui traîne sur tm-tooling |
Le détail est dans Secrets et accès.
L'application
Ce qui relève de l'API (cookies HttpOnly, jeton CSRF, hachage des mots de passe, droits par rôle) est décrit dans les parties Backend et Cybersécurité. Côté infrastructure, CORS_ORIGINS limite les sites autorisés à appeler l'API avec des cookies à https://time.jostud.com.
Les limites connues
Elles sont listées et assumées dans Limites et améliorations : Jenkins exposé derrière sa seule page de connexion, deploy dans le groupe docker (équivalent root), Jenkins en root avec le socket Docker, jeton GitHub classique, SSH ouvert à tous sans fail2ban, entre autres.