regles-qa-anssi.md 5616 octets

Règles QA & conformité ANSSI

Ce document définit les règles de qualité et de sécurité applicables à tout le projet gitrust. Chaque lot doit satisfaire ces règles avant merge.


1. Gates de compilation obligatoires

Toute modification doit passer ces 4 gates sans erreur :

GateCommandeCritère
Formatagecargo fmt --all -- --checkZéro diff
Lintingcargo clippy --workspace -- -D warningsZéro warning
Tests unitairescargo test --workspace100% pass
Build CSSnpx tailwindcss -i static/css/input.css -o static/css/style.css --minifySi templates modifiés

Gates supplémentaires (à mettre en place)

GateOutilRôle
Audit dépendancescargo auditDétection CVE dans les deps
Licences & banscargo deny checkLicences compatibles, pas de crate bannie
Secrets dans le codeRecherche de patterns sensiblesPas de token/mot de passe en dur

2. Règles de sécurité (ANSSI PA-074)

2.1 Lints Rust obligatoires (déjà en place)

#![forbid(unsafe_code)]                    // core, web, hooks
#![deny(unsafe_code)]                      // git, ssh (FFI nécessaire)
#![deny(clippy::unwrap_used)]
#![deny(clippy::expect_used)]
#![deny(clippy::panic)]
#![deny(clippy::indexing_slicing)]
#![deny(clippy::mem_forget)]

2.2 Checklist sécurité par feature

Avant toute implémentation touchant l'authentification, les secrets ou les permissions, vérifier :

  • Secrets jamais en clair en base — hash SHA-256 ou bcrypt
  • Secrets jamais loggés — vérifier tracing::info/debug/warn, Display et Debug impls ne révèlent pas le secret
  • Comparaison constant-timesubtle::ConstantTimeEq pour toute validation de secret (pas de == sur des hash)
  • Rate-limiting — endpoint d'authentification protégé
  • CSRF — token valide sur toute action mutante (POST/PUT/DELETE)
  • Ownership vérifiée (anti-IDOR) — le user ne peut agir que sur ses propres ressources (vérifier user_id côté serveur)
  • Expiration obligatoire — tout token/session a une durée de vie max
  • Audit log — création, révocation, utilisation suspecte tracées
  • Zeroize — types sensibles implémentent Zeroize/ZeroizeOnDrop
  • Path traversal — validation des chemins disque (pas de .., /, \)

2.3 Marqueurs SEC-

Le code utilise des commentaires // SEC-XX pour tracer les décisions de sécurité. Tout nouveau contrôle doit être marqué avec le prochain numéro disponible dans sa catégorie :

PréfixeCatégorieExemples
SEC-CCryptographieTiming attack, CSRF, PKCE
SEC-HHTTP/HeadersX-Forwarded-For, cookies, nonce
SEC-LLogique métierHashing, validation, defaults
SEC-MMémoire/sessionsRate-limit DoS, refresh tokens

3. Tests requis par catégorie

3.1 Matrice de couverture

CatégorieQuand appliquerExemples
UnitaireLogique pure (validation, parsing, conversion)RepoSlug::new("../evil") → erreur
IntégrationService avec DB (CRUD, contraintes, transactions)PatService::validate token expiré → None
HandlerEndpoint HTTP (status, redirect, CSRF, auth)POST sans CSRF → 403
E2E PlaywrightFlow utilisateur completCréer token → copier → cloner un dépôt
Sécurité négatifTout bypass imaginableToken user A sur ressource user B → 401

3.2 Règles de tests

  1. Tests d'intégration sur vraie DB — pas de mocks pour la couche persistence (les mocks masquent les bugs de migration)
  2. Tests négatifs obligatoires — pour chaque chemin heureux, tester au moins : input invalide, non-authentifié, non-autorisé, expiré, révoqué
  3. Tests E2E en français — cohérent avec l'UI (locale fr-FR)
  4. Pas de sleep() dans les tests — utiliser des retry/poll avec timeout
  5. Données de test isolées — chaque test crée ses propres données (pas de dépendance sur l'ordre d'exécution)

4. Règles de code

4.1 Framework boundary

  • Ne jamais modifier crates/rustwarden-core/
  • Réutiliser les services framework avant d'implémenter (auth, users, sessions, ResourceService, i18n, middleware)
  • Si un service manque, l'étendre côté gitrust (wrappers, trait impls)

4.2 Assets

  • Zéro CDN — tous les CSS/JS servis depuis static/
  • La CSP du framework bloque les domaines externes

4.3 Gestion d'erreurs

  • GitrustError avec IntoResponse pour le mapping HTTP
  • Pas de .unwrap() / .expect() / panic!() / [index]
  • Errors utilisateur : messages génériques (pas de leak d'info interne)

4.4 Validation aux frontières

  • Valider les inputs utilisateur (formulaires, query params, headers)
  • Ne pas re-valider entre services internes
  • Newtypes avec validation à la construction (RepoSlug, TeamSlug, Fingerprint, TokenHash)

5. Checklist pré-merge

Avant chaque merge de lot :

  • cargo fmt --all -- --check passe
  • cargo clippy --workspace -- -D warnings passe
  • cargo test --workspace — tous les tests passent
  • Tests E2E Playwright passent (npm run test:e2e)
  • CSS rebuild si templates modifiés
  • Aucun secret en clair dans le code ou les logs
  • Checklist sécurité §2.2 validée (si applicable)
  • Pas de modification dans crates/rustwarden-core/