Files
home_stock/docs/adr/0004-pas-authentification-reseau-local.md
2026-01-28 19:22:30 +01:00

8.7 KiB

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

# 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

# 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é :

# 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é