# ADR-0004 — Pas d'authentification (réseau local uniquement) - Statut : accepted - Date : 2026-01-27 --- ## Contexte HomeStock est une application web self-hosted destinée à un usage mono-utilisateur sur un réseau local domestique. La question de la sécurité d'accès se pose : **Contraintes du projet** : - **Déploiement** : Réseau local 10.0.0.0/22, pas d'exposition Internet prévue - **Utilisateurs** : Mono-utilisateur (propriétaire du domicile) - **Données** : Inventaire personnel, factures (non sensibles au sens RGPD) - **Accès physique** : Réseau domestique, appareils de confiance uniquement **Questions à résoudre** : 1. Faut-il implémenter un système d'authentification (login/password) ? 2. Si oui, quel niveau de sécurité est nécessaire ? 3. Quels sont les risques réels d'un accès non authentifié sur réseau local ? L'authentification ajoute de la complexité (gestion sessions, hash passwords, UI login) et peut dégrader l'expérience utilisateur (saisie répétée de credentials) pour un bénéfice de sécurité potentiellement faible dans ce contexte. --- ## Décision **Nous ne déployons PAS de système d'authentification pour le MVP.** L'application est accessible librement sur le réseau local sans login ni password. ### Justification 1. **Périmètre réseau contrôlé** : Réseau domestique 10.0.0.0/22, tous les appareils sont de confiance 2. **Pas d'exposition Internet** : Application non accessible depuis l'extérieur, pas de port forwarding 3. **Mono-utilisateur** : Pas de besoin de gestion de sessions ou de rôles 4. **Simplicité UX** : Accès immédiat à l'application, pas de friction login 5. **Données non critiques** : Inventaire domestique et factures, pas de données bancaires ou médicales ### Périmètre de sécurité - ✅ **Réseau local uniquement** : Application bind sur IP privée, pas 0.0.0.0 - ✅ **HTTPS optionnel** : TLS pour chiffrement en transit si certificat local disponible - ✅ **Firewall** : Ports fermés en dehors du réseau local (configuration routeur) - ❌ **Pas de login/password** : Accès direct à l'application - ❌ **Pas de sessions** : Pas de gestion de tokens ou cookies d'authentification - ❌ **Pas de RBAC** : Pas de rôles ou permissions (mono-utilisateur) ### Configuration réseau recommandée ```yaml # docker-compose.yml services: backend: ports: - "10.0.0.X:8000:8000" # Bind IP privée uniquement, pas 0.0.0.0:8000 environment: - ALLOWED_HOSTS=10.0.0.0/22 # Whitelist réseau local ``` --- ## Alternatives considérées ### 1. Authentification basique (login/password) **Description** : Page de connexion avec username/password, session cookie **Avantages** : - ✅ Protection contre accès non autorisé sur réseau local - ✅ Traçabilité des accès (logs) - ✅ Possibilité multi-utilisateurs future facilitée **Inconvénients** : - ❌ Complexité additionnelle (hash passwords, sessions, CSRF, refresh tokens) - ❌ UX dégradée (saisie credentials à chaque accès) - ❌ Gestion mot de passe oublié nécessaire - ❌ Sécurité illusoire si appareil compromis (cookies volés) **Verdict** : ❌ **Rejeté pour MVP** - Bénéfice limité sur réseau local de confiance, complexité injustifiée ### 2. Authentification par IP (whitelist) **Description** : Autoriser uniquement certaines IPs du réseau local **Avantages** : - ✅ Simple à implémenter (middleware FastAPI) - ✅ Pas d'UI login **Inconvénients** : - ❌ Gestion fastidieuse des IPs autorisées - ❌ DHCP complique le suivi (IPs dynamiques) - ❌ Pas de granularité utilisateur **Verdict** : ❌ **Rejeté** - Complexité sans bénéfice majeur, réseau déjà isolé ### 3. Authentification par certificat client (mTLS) **Description** : Certificats X.509 pour authentifier les appareils **Avantages** : - ✅ Sécurité forte - ✅ Pas de password à mémoriser **Inconvénients** : - ❌ Complexité extrême (PKI, distribution certificats) - ❌ Configuration browser complexe - ❌ Totalement surdimensionné pour le cas d'usage **Verdict** : ❌ **Rejeté** - Overkill absolu ### 4. Pas d'authentification (notre choix) **Description** : Accès libre sur réseau local **Avantages** : - ✅ Simplicité maximale (pas de code auth) - ✅ UX optimale (accès instantané) - ✅ Maintenance réduite - ✅ Adapté au contexte mono-utilisateur réseau local **Inconvénients** : - ⚠️ Accès libre pour tout appareil sur réseau local - ⚠️ Pas de traçabilité utilisateur - ⚠️ Si exposition Internet accidentelle = vulnérabilité **Verdict** : ✅ **Choisi** - Solution adaptée au contexte avec mitigations appropriées --- ## Conséquences ### Positives 1. **Simplicité code** : Pas de code d'authentification, sessions, CSRF protection 2. **UX fluide** : Accès immédiat, pas de friction login 3. **Pas de gestion passwords** : Pas de hash, reset password, rotation 4. **Maintenance réduite** : Pas de vulnérabilités auth à monitorer (OWASP Top 10) 5. **Performance** : Pas de vérification session sur chaque requête ### Négatives et risques 1. **Exposition accidentelle Internet** : Si port forwarding activé par erreur → accès public 2. **Appareil compromis sur réseau** : Malware sur laptop/smartphone pourrait accéder à l'app 3. **Visiteurs réseau** : Invités connectés au WiFi domestique peuvent accéder à l'app 4. **Pas de traçabilité** : Impossible de savoir qui a modifié/supprimé des données ### Mitigations implémentées 1. **Bind IP privée uniquement** : Backend écoute sur 10.0.0.X:8000, pas 0.0.0.0 2. **Firewall routeur** : Ports 8000/5173 fermés en WAN, ouverts LAN uniquement 3. **HTTPS optionnel** : Certificat auto-signé pour chiffrement en transit 4. **Logging applicatif** : Logs des actions (créer/modifier/supprimer items) avec IP source 5. **Backup régulier** : Scripts de backup pour récupération en cas d'actions malveillantes 6. **Documentation claire** : Avertissement dans README sur importance isolation réseau ### Mitigations à envisager (post-MVP) 1. **Mode "invité" simple** : Code PIN basique si besoin de partager l'accès temporairement 2. **Alerte exposition** : Check au startup si l'app est accessible depuis Internet (API externe) 3. **Read-only mode** : Mode lecture seule pour appareils moins fiables --- ## Impacts techniques ### Code simplifié Pas de code d'authentification signifie : - Pas de modèle `User` en base - Pas de hash passwords (bcrypt, argon2) - Pas de gestion sessions/tokens - Pas de middleware CSRF protection - Pas d'endpoints `/login`, `/logout`, `/register` - Pas d'UI login/signup ### Configuration Docker ```yaml # docker-compose.yml services: backend: ports: - "10.0.0.50:8000:8000" # IP privée fixe uniquement environment: - ALLOWED_ORIGINS=http://10.0.0.50:5173,http://localhost:5173 - CORS_ALLOW_CREDENTIALS=false # Pas de cookies ``` ### Logging renforcé Même sans auth, logger les actions pour traçabilité : ```python # Exemple log logger.info( "Item created", extra={ "item_id": item.id, "item_name": item.name, "source_ip": request.client.host, "user_agent": request.headers.get("user-agent") } ) ``` ### Évolution future Si exposition Internet devient nécessaire (accès depuis extérieur) : 1. **Ajouter authentification** : Login simple (username/password) + session cookie 2. **Reverse proxy avec auth** : Traefik BasicAuth ou OAuth2 Proxy 3. **VPN** : Accès via WireGuard/Tailscale (recommandé) 4. **Cloudflare Access** : Zero-trust avec auth externe --- ## Notes Cette décision est **contextuelle** et adaptée à HomeStock : - ✅ Réseau local domestique contrôlé - ✅ Mono-utilisateur - ✅ Données non critiques Elle serait **inappropriée** pour : - ❌ Application exposée sur Internet - ❌ Multi-utilisateurs - ❌ Données sensibles (bancaires, médicales, secrets) - ❌ Environnement professionnel **Analogie** : C'est comme ne pas mettre de serrure sur la porte de sa chambre dans sa propre maison (réseau local) vs mettre une serrure sur la porte d'entrée (exposition Internet). Si le contexte change (exposition Internet, ajout utilisateurs), cette décision devra être revisitée et l'authentification ajoutée. L'architecture modulaire (ADR-0002) facilite cet ajout futur sans refonte majeure. **Principe appliqué** : "Security proportionate to risk" - Ne pas sur-sécuriser quand le risque est faible et contrôlé. --- **Contributeurs** : Gilles (décideur) + Claude Code (architecte) **Avertissement important** : Cette configuration est sécurisée UNIQUEMENT si le réseau local est isolé d'Internet. Vérifier régulièrement que : 1. Aucun port forwarding n'est configuré sur le routeur 2. Aucun service de tunnel (ngrok, etc.) n'est actif 3. Le firewall du routeur est correctement configuré