ADR-0027 — OWASP Top 10, RGAA / accessibilité et responsivité (cadre transverse)¶
Date : 2026-07-29
Catégorie : A (standards transverses sécurité + UX — cadre opposable aux agents et aux revues)
Décideur : Lead architecte DYNORS
Statut : Acceptée
S'appuie sur : ADR-0013 (JWT/JWKS), ADR-0014 (cookies), ADR-0008/0020 (transit SLY), ADR CDP (docs/adr/ADR-2026-05-15-protection-donnees-personnelles-cdp.md), doctrine SLY / Vault / inter-app
Référentiels externes : OWASP Top 10:2025, RGAA 4.1, WCAG 2.2 niveau AA
Contexte¶
Les fronts et APIs DYNORS (B2C .sn, B2B, intranet) avancent sans cadre unique opposable sur :
- Sécurité applicative — mentions OWASP éparses (PAIEMENT, rapports ZAP/Trivy) mais pas de mapping A01–A10 → contrôles DYNORS ;
- Accessibilité — contrastes WCAG cités dans la charte ERP, socle a11y « au passage » DAWALALE, pas de politique RGAA / niveaux par surface ;
- Responsivité — desktop-first ERP vs mobile B2C, sans règle claire « où c’est obligatoire / où ce n’est pas ».
Sans ADR, chaque app (ou agent) réinvente ou oublie : XSS/CSP, fail-open entitlements, JWT en localStorage, formulaires sans label, landings non utilisables mobile, écrans métier « cassés » sur tablette terrain.
Décision¶
Trois politiques obligatoires pour toute UI/API livrée sous marque DYNORS ou domaine de marque produit. Non-conformité = bloquant revue / gate RMOA→PROD sauf dérogation tracée (issue + justification CTO/lead).
1. OWASP Top 10:2025 — mapping DYNORS (opposable)¶
Référence canonique : OWASP Top 10:2025 (pas 2021). Chaque item a un contrôle DYNORS minimal. Les ADR déjà acceptés priment ; cet ADR les rappelle et comble les trous UX/ops.
| # | Risque OWASP | Contrôle DYNORS minimal (non négociable) |
|---|---|---|
| A01 | Broken Access Control | Tenant uniquement depuis JWT validé / transit SLY signé (jamais header/body métier). RBAC + entitlements fail-closed. aud par app (ADR-0011). SSRF : pas d’URL libre vers l’interne ; sorties via SLY / allowlist. CSRF : cookies SameSite + mutations authentifiées. |
| A02 | Security Misconfiguration | Profils Spring fail-fast hors-local si secrets absents. Headers : HSTS, CSP (pas unsafe-inline en cible prod), X-Content-Type-Options, Referrer-Policy, Permissions-Policy. Debug / Actuator sensibles non exposés hors réseau interne. CORS : same-origin hors-prod (ADR-0018) ; prod = allowlist explicite. |
| A03 | Software Supply Chain Failures | Dépendances com.dynors.* sans -SNAPSHOT hors chantier local. Images signées / registry GitLab. SAST (Semgrep) + Trivy CRITICAL en CI avant RMOA. Pas de secrets dans Git (Vault). Cosign / SBOM : trajectoire SIRRAT (pas de contournement « image :latest » en prod). |
| A04 | Cryptographic Failures | TLS partout hors local. JWT RS256 + JWKS + kid (ADR-0013) ; HS256 interdit en prod. Secrets dans Vault. Données Sensible (santé, IBAN complet) : chiffrement au repos / Transit. Cookies HttpOnly Secure host-only (ADR-0014) — jamais token en localStorage / JS readable pour session. |
| A05 | Injection | Bean Validation (@Valid) au bord. Requêtes paramétrées / JPA — zéro concat SQL. Escape sortie HTML (framework). Pas d’eval / innerHTML non sanitisé. Uploads via MEDIA (fileId), jamais chemin libre disque. |
| A06 | Insecure Design | Threat model léger par surface publique (auth, paiement, admin). Doctrine : SLY non contournable inter-app ; least privilege ; maker-checker sur flux financiers sensibles. « Features » qui contournent JWT/tenant = rejet revue. |
| A07 | Authentication Failures | Auth centralisée dynors-auth. Rate-limit login. Pas de messages qui leakent l’existence du compte au-delà du nécessaire. Session : cookies isolés ; refresh path restreint. MFA : roadmap produits sensibles (paiement admin, santé) — à activer par app, pas optionnel en prod admin critique sans plan. |
| A08 | Software / Data Integrity Failures | Webhooks PSP signés + idempotence. Transit SLY HMAC (V3). Pas de désérialisation non fiable. CI : artefacts attestés ; pas de « hotfix » image non taguée en prod. |
| A09 | Security Logging & Alerting Failures | Audit des refus authz, login échec, mutations admin, paiements. Jamais de secret / JWT / PAN / cookie dans les logs. Corrélation traceId / lane. Alerting : brancher ZAP/Trivy findings dans SIRRAT avant PV RMOA client. |
| A10 | Mishandling of Exceptional Conditions | Fail-closed entitlements / auth. Erreurs API via contrat dynors-api-errors (pas de stack trace au client). Timeouts / circuit sur appels SLY. Pas de catch générique qui avale et continue « comme si OK ». |
Outils : Semgrep + Trivy en CI ; OWASP ZAP (baseline puis full) sur URLs SLY / domaines marque avant gate RMOA→PROD. Absence d’outil ≠ exemption : checklist manuelle A01–A10 dans le PV.
2. Accessibilité — WCAG 2.2 AA + politique RGAA¶
2.1 Principe¶
- Socle international : WCAG 2.2 niveau AA pour tout contenu UI livré à un utilisateur humain.
- Référentiel opérationnel DYNORS : RGAA 4.1 (critères / tests) comme checklist d’audit — y compris hors France — afin d’avoir une grille unique (images, formulaires, navigation clavier, contrastes, ARIA, documents…).
- L’obligation légale française RGAA ne s’applique pas telle quelle au Sénégal ; la politique produit DYNORS l’adopte volontairement comme standard qualité (crédibilité institutionnelle, inclusion, alignement partenaires UE).
2.2 Niveaux par surface (pour ne plus se tromper)¶
| Surface | Exemples | Niveau exigé | Contenu minimal |
|---|---|---|---|
| S0 — Publique / B2C critique | Landings *.sn, DAWALALE Learn/Drive/Exam, ELISA citoyen, Medisen patient, parcours paiement |
RGAA : conformité progressive → totale ; WCAG 2.2 AA gate prod | Contrastes AA, focus visible, labels, alternatives textuelles, clavier seul, erreurs de formulaire liées au champ, pas de piège clavier, lang, titres, skip link |
| S1 — B2B métier dense | FISCAL B2B, JARAAF, SuperGest back-office, TRACIUM, Comptoir | WCAG 2.2 AA sur contrastes + clavier + formulaires ; audit RGAA échantillon (écrans critiques) | Tables : en-têtes ; modales : focus trap ; toasts : non seuls porteurs d’info critique |
| S2 — Intranet / admin DYNORS | RAGNAR, TAKKU, RED, HEISENBERG, SLY Portal, SIRRAT | Socle a11y (contrastes AA charte, labels, clavier navigation principale) | Audit RGAA complet non bloquant V1 ; dette tracée |
| S3 — Documents / PDF générés | Factures, attestations, bulletins | PDF accessibles cible (tags, ordre de lecture) pour S0/S1 réglementaire | Phase 1 : au minimum texte extractible ; Phase 2 : PDF/UA sur docs opposables |
2.3 Interdits (tous niveaux)¶
- Information uniquement par la couleur.
- Captcha inaccessible sans alternative.
- Contenu qui clignote > 3/s.
- Boutons / liens sans nom accessible.
- Overlay qui bloque le clavier ou le lecteur d’écran sans échappatoire.
autofocusagressif qui piège ; lecteurs d’écran non testés au moins une fois sur S0 avant prod.
2.4 Preuves¶
- Revue PR front : checklist RGAA résumée (10 points socle) pour S0/S1.
- Gate prod S0 : audit (manuel ou outil type axe/Lighthouse a11y + relecture clavier) joint au PV.
- Dérogation : issue
a11y-debt-*avec échéance ≤ 90 j, sinon pas de nouvelle feature sur la surface concernée.
3. Responsivité — où c’est nécessaire (et où non)¶
| Classe | Obligation | Breakpoints cibles | Exemples |
|---|---|---|---|
| R1 — Mobile-first obligatoire | Viewport fluide ; utilisable 320–428 px sans scroll horizontal ; touch targets ≥ 44 px | 360 / 768 / 1024 / 1280 | Landings marque, DAWALALE candidat, ELISA, Medisen patient, paiement mobile money, auth B2C |
| R2 — Desktop-first + tablette utilisable | Conception desktop ; cassures pour ≥ 768 px (lecture / actions primaires) ; pas d’obligation smartphone natif | 768 / 1024 / 1440 | JARAAF manager, FISCAL B2B, SuperGest back-office, Comptoir, RAGNAR |
| R3 — Desktop / kiosk figé (documenté) | Largeur mini documentée ; pas de promesse mobile | — | HEISENBERG BI lourde, consoles ops SIRRAT, POS Electron si viewport matériel figé dans la spec |
| R4 — Native / offline | Responsive dans le shell (Electron/mobile) selon spec produit | Selon device | SuperGest POS, Medisen offline |
Règles :
- Une maquette ou un front S0 / R1 non responsive = rejet (même si le back est prêt).
- Un ERP R2 peut refuser un layout smartphone complet, mais les actions critiques (valider, payer, approuver) doivent rester actionnables en tablette.
viewportmeta obligatoire sur tout HTML servi.- Pas de largeurs fixes en px sur conteneurs principaux (sauf canvas BI / grilles POS documentées).
- Tests manuels : au moins un device étroit + un desktop avant merge S0 ; Playwright/Chromium resize accepté comme preuve.
4. Articulation CI / revue / agents¶
- Agents & devs : avant de livrer une UI ou une API exposée, vérifier A01–A10 + classe S + classe R de la surface.
- SIRRAT / PV : case « ADR-0027 » (OWASP + a11y + responsive) sur gate RMOA→PROD.
- Charte visuelle (
docs/CONTEXT_CLAUDE_ERP_INTERFACES.md) : ratios WCAG AA = plancher ; RGAA complète la grille fonctionnelle. - En cas de conflit maquette vs a11y/sécurité : a11y/sécurité gagnent ; la maquette est corrigée (règle respect-maquettes amendée par cet ADR).
Conséquences¶
Positif : un seul cadre pour ne plus « oublier » CSP, labels, mobile B2C, fail-closed ; alignement audits ZAP / RGAA / Lighthouse ; crédibilité institutionnelle.
Coût : effort front S0 (DAWALALE, ELISA, Medisen) ; dette S2 acceptée et tracée ; headers CSP à introduire progressivement (report de scripts inline).
Hors scope : certification légale RGAA française complète (déclaration d’accessibilité publique) — recommandée pour sites .sn grand public, pas bloquante V1 si niveau S0 AA + checklist RGAA passent.
Alternatives considérées¶
| Option | Verdict |
|---|---|
| OWASP seulement, a11y « plus tard » | Rejeté — déjà source d’oublis UI B2C |
| WCAG seul sans RGAA | Rejeté — pas de grille d’audit opérationnelle commune |
| Responsive partout y compris BI | Rejeté — coût injustifié ; classes R1–R4 |
| Laisser chaque app décider | Rejeté — objet de cet ADR |
Plan d’exécution¶
- Publier cet ADR + entrée registre + nav MkDocs + règle Cursor pointant ici.
- Checklist PR (10 lignes) dans les templates front / handoff.
- Brancher headers sécu (A02) via nginx / Spring Security sur staging.
- Pilote a11y+responsive : DAWALALE S0 (déjà partiellement amorcé) puis Medisen patient.
- ZAP baseline sur SLY staging avant premier go-live produit.
Suivi (critères de succès)¶
- [ ] Toute nouvelle UI S0 mergeée après la date d’acceptation respecte R1 + socle RGAA.
- [ ] Gate RMOA→PROD documente A01–A10 (ou renvoie aux preuves CI).
- [ ] Aucun token de session navigateur hors cookie HttpOnly (régression A04/A07).
- [ ] Entitlements / auth : zéro fail-open constaté en revue (A01/A10).
Références¶
- https://owasp.org/Top10/2025/
- https://accessibilite.numerique.gouv.fr/ (RGAA)
- https://www.w3.org/TR/WCAG22/
- ADR-0013, ADR-0014, ADR-0018, ADR-0008, ADR-0020
docs/adr/ADR-2026-05-15-protection-donnees-personnelles-cdp.mddocs/CONTEXT_CLAUDE_ERP_INTERFACES.md(contrastes AA)docs/security/RAPPORT_SECURITE_HEBDO_*.md(ZAP/Trivy)