Architecture robuste pour une application d'organisation sensible
Approche volontairement agnostique de la technologie : les principes ci-dessous s'appliquent quel que soit le langage, le framework mobile ou le framework backend choisis.
Le problème de fond
Dans une organisation sensible (ONG, santé, finance, sécurité publique, etc.), l'erreur la plus courante est de construire une app "normale" avec un vernis de sécurité ajouté après coup. Le symptôme typique le point d'entrée du login qui fait une requête directe sur la base de données illustre un problème plus large : l'absence de séparation entre couches, ce qui rend impossible d'auditer, de limiter, de faire tourner les secrets, ou de remplacer un composant sans tout casser.
Les principes qui doivent guider l'architecture, indépendamment de la stack :
Defense in depth : aucune couche ne doit être le seul rempart.
Least privilege : chaque composant n'a accès qu'aux données dont il a strictement besoin.
Zero trust interne : même les appels entre vos propres services sont authentifiés et chiffrés.
Séparation authentification / logique métier : l'auth ne doit jamais être "juste un champ de plus" dans le contrôleur métier.
Traçabilité : tout accès sensible est journalisé, horodaté, non falsifiable.
Remplaçabilité : chaque brique (base de données, fournisseur d'identité, stockage) doit pouvoir être changée sans réécrire le reste.
Vue d'ensemble de l'architecture

Points clés :
Le Gateway est le seul point d'entrée public ; il ne parle jamais directement à une base de données.
Le service d'authentification est isolé, avec sa propre base, distincte de la base métier. Un compromis du service métier ne donne pas accès aux identités.
Le service d'audit reçoit des événements en asynchrone (pas de couplage fort), ce qui garantit que la journalisation ne peut pas être contournée par le code métier.
Le flux d'authentification, correctement découplé
C'est le cœur du problème initial : le login ne doit jamais interroger directement la table des utilisateurs depuis le point d'entrée HTTP. Voici le flux correct.

Ce qui change concrètement par rapport à "la requête directe dans le login" :
Anti-pattern | Bonne pratique |
|---|---|
Le point d'entrée exécute directement une requête SQL sur la table des utilisateurs | Il appelle un cas d'usage / service, qui appelle un Repository |
Mot de passe comparé en clair ou avec un hash faible (MD5/SHA1) | Argon2id (ou bcrypt à défaut), comparaison en dehors de la couche SQL |
Pas de limite de tentatives | Rate limiting via cache + verrouillage progressif |
Un seul composant gère tout (auth + métier + données personnelles) | Service d'authentification isolé, base séparée, accessible uniquement en interne |
Clé de signature en dur dans le code | Clé récupérée depuis un gestionnaire de secrets, rotation possible sans redéploiement |
Pas de trace de qui s'est connecté / a échoué | Événements envoyés à un service d'audit, immuables |
Architecture en couches côté backend

Règles à imposer, quel que soit le framework backend :
Le point d'entrée HTTP ne fait jamais de requête brute. Il valide l'entrée et délègue.
Toute règle métier passe par un cas d'usage/service, testable indépendamment du framework.
L'accès aux données passe par un Repository (interface + implémentation), ce qui permet de changer de moteur de base de données ou de simuler en test.
L'autorisation (qui a le droit de faire quoi) est gérée par des règles centralisées (policies/gates), jamais par des conditions dispersées dans le code.
Chaque action sensible (lecture d'un dossier, export, modification de droits) déclenche un événement capté par le service d'audit.
Sécurité côté application cliente (mobile)

Points essentiels, indépendants du framework mobile :
Jamais de token ou de secret dans un stockage non chiffré : utiliser le coffre sécurisé natif de l'OS (chiffrement matériel).
Certificate pinning pour empêcher les attaques par interception même sur un appareil compromis.
Détection basique de root/jailbreak pour restreindre l'affichage de données sensibles sur un appareil compromis (sans en faire l'unique protection).
Verrouillage automatique de l'app (biométrie/code) au retour au premier plan.
Aucune donnée sensible en cache local non chiffré ; désactiver les captures d'écran sur les vues sensibles si pertinent.
Isolation et infrastructure

Les bases de données sont dans un sous-réseau sans accès sortant à internet.
Chiffrement au repos (disques) et en transit (canal chiffré entre tous les services internes).
Secrets (clés de signature, identifiants de base, clés d'API tierces) gérés par un gestionnaire de secrets dédié, jamais dans le code ou en clair sur le dépôt.
Sauvegardes chiffrées, testées régulièrement (un backup non restauré n'est pas un backup).
Cycle de vie et intégration continue
Scan de dépendances et de secrets à chaque contribution, avant fusion du code.
Analyse statique du code, quel que soit le langage.
Tests d'intrusion réguliers, en particulier sur le flux d'authentification et les points d'accès aux données sensibles.
Déploiements permettant la rotation des secrets sans interruption (pas de secret figé dans une image de déploiement).
Environnements de test sans données réelles (anonymisation ou données synthétiques).
Résumé ce qu'il ne faut jamais faire
Requête directe à la base de données depuis un point d'entrée HTTP (login ou autre).
Mot de passe comparé ou stocké sans hash adapté (Argon2id/bcrypt).
Un seul composant qui gère à la fois auth, données métier et logs.
Secrets en dur dans le code ou dans un fichier de configuration versionné.
Tokens stockés en clair côté client.
Absence de rate limiting sur les points d'accès d'authentification.
Autorisation dispersée en conditions ad hoc au lieu de règles centralisées.
Logs d'audit facultatifs ou modifiables après coup.
L'idée générale : chaque couche doit pouvoir être remplacée, testée et attaquée isolément sans mettre en péril le reste du système. C'est ce découplage — pas un outil ou un framework en particulier qui fait la robustesse d'une architecture pour une organisation sensible.