PD-26 — Scénarios de tests contractuels
📚 Navigation User Story
| Document | | | ---------- | -- | | 📋 [Spécification](PD-26-specification.md) | | | 🛠️ [Plan d'implémentation](PD-26-plan.md) | | | 🧪 **Tests contractuels** | *(ce document)* | | ✅ Critères d'acceptation | *(à venir)* | | 📝 Retour d'expérience | *(à venir)* | [← Retour à auth-identity](../PD-182-epic.md) · [↑ Index User Story](index.md)
1. Références
- Spécification : PD-26-specification.md
- Epic : PD-182 — AUTH
- JIRA : PD-26
2. Matrice de couverture
| ID Invariant | ID Critère | ID Test | Couverture | Commentaire |
| INV-01 | CA-01 | TC-NOM-01 | Oui | Absence de token |
| INV-02 | CA-02 | TC-NOM-02 | Oui | Signature invalide |
| INV-02 | CA-03 | TC-NOM-03 | Oui | Issuer incorrect |
| INV-02 | CA-04 | TC-NOM-04 | Oui | Audience incorrecte |
| INV-02 | CA-05 | TC-NOM-05 | Oui | Expiration token |
| INV-02 | CA-06 | TC-NOM-06 | Oui | Algorithme interdit |
| INV-05 | CA-07 | TC-NOM-07 | Oui | Claims requis (liste normative) |
| INV-09 | CA-07 | TC-NOM-07 | Oui | Claims normatifs requis |
| INV-10/INV-11 | CA-08 | TC-NOM-08 | Oui | Autorisation accordée avec roles/scopes conformes (HYBRID) |
| INV-10/INV-11 | CA-08 | TC-NOM-12 | Oui | Refus si roles/scopes absents ou insuffisants |
| INV-07 | CA-09 | TC-NOM-09 | Oui | Isolation environnements |
| INV-04 | CA-10 | TC-NOM-10 | Oui | Non-fuite logs (liste blanche) |
| INV-08 | CA-11 | TC-NOM-11 | Oui | Résilience JWKS (fail-closed + signal dégradé) |
| INV-12 | CA-12 | TC-NOM-13 | Oui | Protection brute force (verrouillage après N échecs) |
2bis. Prise en charge des cas PD-235 délégués (backend)
| Réf PD-235 | Test PD-26 | Couverture | Commentaire |
| TC-ERR-01 | TC-PD235-ERR-01 (alias TC-NOM-11) | Oui | IdP/JWKS/Discovery indisponible → fail-closed + signal health/readiness explicite |
| TC-ERR-03 | TC-PD235-ERR-03 (alias TC-NOM-11) | Oui | Signal d’indisponibilité IdP distinct d’un rejet de token invalide |
| TC-NEG-02 | TC-NOM-05 | Oui | Rejet systématique d’un token expiré côté backend |
| TC-NEG-04 | TC-PD235-NEG-04 (alias TC-NOM-07) | Oui | Rejet d’un token sans identité valide (sub/claims requis absents) |
3. Scénarios de test – Flux nominaux
TEST-ID: TC-NOM-01
Référence spec: INV-01, CA-01
GIVEN
- Une API marquée comme protégée
WHEN
- Une requête est envoyée sans en-tête Authorization
THEN
- La requête est rejetée avec un état "non authentifié"
- Aucun traitement applicatif n’est exécuté
TEST-ID: TC-NOM-02
Référence spec: INV-02, CA-02
GIVEN
- Une API protégée
WHEN
- Un JWT avec une signature invalide est fourni
THEN
- La requête est rejetée avec un état "non authentifié"
TEST-ID: TC-NOM-03
Référence spec: INV-02, CA-03
GIVEN
- Un backend configuré avec un issuer X
WHEN
- Un JWT avec iss = Y (Y ≠ X) est fourni
THEN
- La requête est rejetée
TEST-ID: TC-NOM-04
Référence spec: INV-02, CA-04
GIVEN
- Un backend configuré avec une audience attendue A
WHEN
- Un JWT ne contenant pas A dans le claim aud est fourni
THEN
- La requête est rejetée
TEST-ID: TC-NOM-05
Référence spec: INV-02, CA-05
GIVEN
- Une API protégée
WHEN
- Un JWT expiré est fourni
THEN
- La requête est rejetée
TEST-ID: TC-NOM-06
Référence spec: INV-02, CA-06
GIVEN
- Une API protégée
WHEN
- Un JWT utilisant un algorithme non autorisé est fourni
THEN
- La requête est rejetée
TEST-ID: TC-NOM-07
Référence spec: INV-05, CA-07
GIVEN
- Une route exigeant un ensemble de claims requis
WHEN
- Un JWT valide mais incomplet est fourni
THEN
- La requête est rejetée selon la politique définie
TEST-ID: TC-NOM-08
Référence spec: INV-05, CA-08
GIVEN
- Une route exigeant un rôle ou scope spécifique
WHEN
- Un JWT valide contenant ce rôle/scope est fourni
THEN
- L’accès est accordé
TEST-ID: TC-NOM-12 Référence spec: INV-10/INV-11, CA-08 GIVEN - Une route déclarant des exigences explicites (rôle et/ou scope, règle AND/OR). WHEN - Un JWT valide mais ne satisfaisant pas ces exigences (rôle/scope absent ou insuffisant) est fourni. THEN - La requête est refusée conformément à la règle déclarée (HYBRID, AND/OR).
TEST-ID: TC-NOM-09
Référence spec: INV-07, CA-09
GIVEN
- Deux environnements isolés A et B
WHEN
- Un token émis en A est utilisé sur B
THEN
- La requête est rejetée
- Le realm/tenant du token est conforme à la REALM_POLICY/TENANT_POLICY (cross-realm/tenant interdit)
TEST-ID: TC-NOM-10
Référence spec: INV-04, CA-10
GIVEN
- Une requête échouant pour cause de token invalide
WHEN
- Les logs applicatifs sont inspectés
THEN
- Aucun token ou secret n’apparaît en clair
- Les entrées de log/audit ne contiennent que les champs autorisés (requestId, sub, tenant, issuer, audience, clientId, code d’erreur, route/ressource, horodatage)
TEST-ID: TC-NOM-11
Référence spec: INV-08, CA-11
GIVEN
- Une indisponibilité du JWKS ou du document de découverte
WHEN
- Un nouveau token est présenté
THEN
- La requête est rejetée (fail-closed)
- Un état de service dégradé est observable via un signal explicite (health/readiness ou metric)
TEST-ID: TC-NOM-13
Référence spec: INV-12, CA-12, PD-27 R6
Délégation: PD-27 TC-NOM-06 (brute force protection)
GIVEN
- Un realm Keycloak configuré avec bruteForceProtected: true et failureFactor: N
- Un utilisateur valide avec MFA activé
WHEN
- N tentatives d'authentification échouent consécutivement (mot de passe ou OTP incorrect)
THEN
- Le compte est verrouillé temporairement (HTTP 400 avec error: "user_temporarily_disabled")
- L'événement LOGIN_ERROR est journalisé dans les logs Keycloak
- Après waitIncrementSeconds, le compte est déverrouillé automatiquement
ARTEFACT:
- Configuration: ProbatioVault-infra/ansible/roles/keycloak-realm/templates/realm.json.j2 (lignes 30-37)
- Paramètres: bruteForceProtected, failureFactor, waitIncrementSeconds, maxFailureWaitSeconds
- Implémentation: test/integration/keycloak/brute-force-protection.e2e-spec.ts
NOTE:
Ce test est exécuté au niveau IdP (Keycloak).
Requiert un utilisateur de test dédié (BRUTE_FORCE_TEST_USER).
4. Scénarios de test – Cas d'erreur
TEST-ID: TC-ERR-01
Référence spec: Cas E10
GIVEN
- Une configuration OIDC incohérente (issuer/audience/JWKS)
WHEN
- Le service démarre
THEN
- Le service expose un état "non prêt" ou échoue explicitement
TEST-ID: TC-PD235-ERR-01 (alias PD-235 TC-ERR-01)
Référence spec: INV-08, CA-11, PD-235 TC-ERR-01/03
GIVEN
- Une indisponibilité IdP/JWKS/Discovery (HTTP 5xx, DNS, timeouts)
WHEN
- Un token est présenté ou une récupération JWKS est requise
THEN
- La requête est rejetée (fail-closed) avec un état explicite (401/503 selon politique)
AND
- L’endpoint health/readiness ou une métrique expose un signal distinct d’un simple token invalide
TEST-ID: TC-PD235-ERR-03 (alias PD-235 TC-ERR-03)
Référence spec: INV-08, CA-11, PD-235 TC-ERR-03
GIVEN
- L’IdP reste indisponible (défaillance persistante)
WHEN
- L’endpoint health/readiness est interrogé
THEN
- L’état de service est dégradé/KO et l’explicite "IdP/JWKS indisponible" est observable
AND
- Aucun token n’est accepté tant que l’état reste dégradé (fail-closed)
5. Tests d’invariants (non négociables)
| Invariant | Test(s) dédiés | Observable | Commentaire |
| INV-01 | TC-NOM-01 | Code/état | Aucune hypothèse implicite |
| INV-02 | TC-NOM-02 à 06 | Rejet | Validation JWT |
| INV-04 | TC-NOM-10 | Logs | Confidentialité |
| INV-09 | TC-NOM-07 | Rejet | Claims normatifs requis |
| INV-10/INV-11 | TC-NOM-08, TC-NOM-12 | Accès/refus | Autorisation HYBRID déterministe |
| INV-07 | TC-NOM-09 | Rejet | Isolation env |
| INV-08 | TC-NOM-11 | État service | Résilience |
| INV-12 | TC-NOM-13 | Verrouillage IdP | Brute force protection (délégué IdP) |
6. Tests de non-régression
| Test ID | Objet | Observable | Commentaire |
| TC-NR-01 | Validation JWT standard | Succès | Aucun changement de règle |
| TC-NR-02 | Autorisation rôles/scopes | Accès/refus | Stabilité des règles |
7. Tests négatifs et adversariaux
| Test ID | Entrée invalide / abus | Résultat attendu | Observable |
| TC-NEG-01 | Token forgé | Rejet | Code/état |
| TC-NEG-02 | Token ancien après rotation clé | Rejet | Code/état |
| TC-NEG-03 | Token d’un autre env | Rejet | Code/état |
| TC-NEG-04 | Injection de secret/claim sensible dans metadata/log | Rejet ou neutralisation ; logs conformes à la liste blanche | Logs/audit |
TEST-ID: TC-NEG-04
Référence spec: INV-04, CA-10
GIVEN
- Une tentative d’injecter un secret (token, header Authorization, claim sensible) dans des champs metadata/log.
WHEN
- L’appel est traité et les logs/audit sont examinés.
THEN
- Le secret n’apparaît pas en clair ; seuls les champs autorisés de la liste blanche sont présents.
- L’appel est rejeté ou neutralisé selon la politique applicative.
TEST-ID: TC-PD235-NEG-04 (alias PD-235 TC-NEG-04)
Référence spec: INV-05, INV-09, CA-07, PD-235 TC-NEG-04
GIVEN
- Un JWT manquant d’identité valide (claim `sub` absent ou tenant/claims requis manquants) ou un token obtenu sans identité vérifiée.
WHEN
- La requête est traitée par le backend
THEN
- Le token est rejeté de manière déterministe (non authentifié)
AND
- Les logs restent conformes à la liste blanche (aucun token/secret en clair)
8. Observabilité requise pour les tests
- État système : readiness / health
- Réponses API : codes d’erreur
- Journaux d’audit : accès refusés
- Signal d’état dégradé JWKS
9. Règles non testables
| Règle | Raison | Impact |
| — | — | — |
10. Verdict QA
- ✅ Testable (règles normatives définies)