Aller au contenu principal

V0.6.1 — HTTPS

Publiée le 14/10/2026.

Documentation fonctionnelle

Ce que change la version pour les collaborateurs

Pourquoi​

Jusqu’à la 0.6.0, l’UI, l’API et le Live étaient servis en HTTP sur quatre ports du Site : sur le Wi-Fi, le mot de passe de l’Administrateur, le cookie de session, les identifiants de caméra saisis à l’ajout et le jeton de l’Aperçu circulaient en clair. Le Site n’a pas de nom de domaine public, donc pas de certificat d’une autorité d’internet ; un certificat auto-signé aurait habitué l’Administrateur à ignorer les avertissements du navigateur.

Ce qu'on peut faire maintenant​

  • Ouvrir ArgOS en HTTPS, sous une seule adresse https://\<IP du Site> : l’UI, l’API et le Live (WebRTC et HLS) passent par le nginx de web, sur le port 443 (réglable).
  • Les anciennes adresses en clair (http://…:8080, http://\<IP du Site>) redirigent vers la même page en HTTPS.
  • Se connecter, administrer les Caméras (détection, ajout, Réglages ONVIF) et regarder le Live H.264 et H.265 comme avant.
  • Les anciens ports de l’API et des Flux (8000, 8888, 8889) ne sont plus exposés sur le réseau ; le cookie de session porte Secure, et CORS a disparu.
  • ArgOS crée seul, au premier lancement, l’Autorité du Site et le certificat du serveur, sans commande openssl. Son empreinte SHA-256 s’affiche au lancement.
  • Depuis le Mac hôte, le lanceur propose d’ajouter l’Autorité du Site au trousseau, puis ouvre https://localhost sans avertissement ; aux lancements suivants, il ne redemande rien.
  • Installer l’Autorité du Site sur un autre poste (macOS, iOS, Windows, Android) en la téléchargeant depuis http://\<IP du Site>/argos-ca.crt, avec une doc pas à pas (« Installer l’Autorité du Site »).
  • Quand l’IP du Site change ou que le certificat approche de l’expiration, un nouveau certificat serveur est créé et servi sans arrêter la stack, avec la même Autorité : rien à réinstaller sur les postes.
  • Un Administrateur qui a son propre certificat (nom de domaine, VPN) peut le déposer à la place de celui d’ArgOS.
  • Le schéma du réseau (conteneurs, ports, flux chiffrés ou en clair) rejoint la doc produit.

Documentation technique

Spec versionnée : docs/specs/v0.6.1-https.md

Issue parente : #59

V0.6.1 — HTTPS

Problem Statement​

L'UI (web, port 8080), l'API (8000), la signalisation WebRTC (WHEP, 8889) et le HLS (8888) sont servis en HTTP, sur quatre origines différentes du même hôte. Sur le Wi-Fi du Site, le mot de passe de l'Administrateur, le cookie de session (sans attribut Secure), les identifiants de caméra saisis à l'ajout (POST /api/essai) et le jeton de l'Aperçu circulent en clair : n'importe quel poste du réseau local peut les lire, ou se faire passer pour ArgOS.

Le Site n'a pas de nom de domaine public : aucune autorité de certification d'internet ne peut lui signer un certificat. Un certificat auto-signé ferait avertir le navigateur à chaque poste, et habituerait l'Administrateur à cliquer sur « continuer » — ce qui ruinerait l'intérêt du HTTPS.

HTTPS est, avec l'authentification des Flux (0.6.2) et la sécurisation d'ONVIF (0.6.3), un préalable à toute installation sur de vraies caméras (docs/securite.md).

Solution​

Le Site n'est plus servi que par une seule origine HTTPS : le nginx du conteneur web termine le TLS sur le port 443 (réglable) et route, sous la même adresse, l'UI, l'API et le Live (WHEP, HLS) vers les conteneurs du Site. Les ports 8000, 8888 et 8889 ne sont plus publiés ; 80 et 8080 ne font que rediriger vers HTTPS. Le cookie de session porte Secure. Avec une seule origine, CORS disparaît.

Le certificat du serveur est signé par l'Autorité du Site, générée une fois par ArgOS sur la machine hôte. L'Administrateur l'installe une fois par poste (Mac, iPhone, PC, Android) : ensuite, le navigateur reconnaît le Site sans avertissement. Le fichier de l'Autorité est servi en HTTP (/argos-ca.crt) et son empreinte SHA-256 s'affiche au lancement, pour vérifier qu'il n'a pas été remplacé en route. Sur la machine hôte, lancer-argos.command propose de l'ajouter au trousseau.

Le certificat serveur couvre localhost, 127.0.0.1 et l'IP du Site sur le réseau local ; il est régénéré seul au démarrage si cette IP change ou s'il approche de l'expiration, avec la même Autorité (rien à refaire sur les postes). Un Administrateur qui a son propre certificat (nom de domaine, VPN) peut le déposer à la place.

Le schéma du réseau (conteneurs, ports, flux, chiffré ou en clair) est mis à jour et rejoint la doc produit.

User Stories​

Se connecter en HTTPS​

  1. En tant qu'Administrateur, je veux ouvrir https://\<IP du Site> et voir le cadenas sans avertissement, pour savoir que je parle au vrai Site et que personne ne lit mon mot de passe.
  2. En tant qu'Administrateur, je veux que mon ancienne adresse http://\<IP du Site>:8080 me redirige vers HTTPS, pour ne pas avoir à changer mes habitudes ni mes favoris.
  3. En tant qu'Administrateur, je veux que le cookie de session ne soit jamais envoyé en clair, même si je tape une adresse en http://.
  4. En tant qu'Administrateur, je veux que l'Administration, l'ajout de Caméra, l'Aperçu, les Réglages et le Live marchent comme avant, sous la même adresse HTTPS.
  5. En tant qu'Administrateur, je veux que l'API et les Flux ne soient plus joignables en HTTP sur leurs anciens ports, pour qu'il n'existe pas de chemin en clair à côté.

Autorité du Site​

  1. En tant qu'Administrateur, je veux qu'ArgOS crée seul, au premier lancement, l'Autorité du Site et le certificat du serveur, sans commande openssl à taper.
  2. En tant qu'Administrateur, je veux télécharger l'Autorité du Site depuis un poste (http://\<IP du Site>/argos-ca.crt) et comparer son empreinte avec celle affichée au lancement, pour être sûr d'installer la bonne.
  3. En tant qu'Administrateur, je veux une doc pas à pas pour installer l'Autorité sur macOS, iOS, Windows et Android.
  4. En tant qu'Administrateur, je veux que lancer-argos.command me propose, une seule fois et avec mon accord, d'ajouter l'Autorité au trousseau du Mac hôte, pour que l'UI qu'il ouvre s'affiche sans avertissement.
  5. En tant qu'Administrateur, je veux que le changement d'IP du Site (nouveau bail DHCP, .env mis à jour) régénère le certificat serveur sans me faire réinstaller l'Autorité sur mes postes.
  6. En tant qu'Administrateur, je veux que le certificat serveur se renouvelle seul avant d'expirer.
  7. En tant qu'Administrateur, je veux savoir ce qui arrive si je perds l'Autorité (volume supprimé) : la réinstaller sur tous les postes.

Mon propre certificat​

  1. En tant qu'Administrateur qui a un nom de domaine ou un VPN avec certificats, je veux déposer mon certificat et sa clé dans un dossier configuré par .env, pour que le Site les serve tels quels, sans Autorité du Site.

Dev​

  1. En tant que développeur, je veux lancer Vite en HTTPS avec le certificat d'ArgOS, sous la même origine que l'API et les Flux, pour développer dans les mêmes conditions qu'en prod (cookie Secure compris, Safari compris).

Documentation​

  1. En tant que lecteur de la doc, je veux un schéma du réseau à jour (conteneurs, ports publiés, réseaux, flux, chacun marqué chiffré ou en clair) dans la doc produit.
  2. En tant que lecteur de docs/securite.md, je veux savoir ce que le HTTPS protège et ne protège pas, qui a accès à la clé de l'Autorité, et ce qui reste en clair (RTSP 8554, réseau des caméras).

Implementation Decisions​

  • Glossaire (docs/glossaire.md) :
    • Autorité du Site : certificat qui permet à un poste de reconnaître le Site en HTTPS ; installée une fois par poste. Avoid : CA, certificat racine, certificat auto-signé.
    • Le certificat serveur reste un détail technique (pas de terme).
  • Une seule origine (ADR 0005) : le nginx de web écoute en TLS sur 443 dans le conteneur, publié sur $\{ARGOS_PORT_HTTPS:-443\}. Routes :
    • / → fichiers statiques de l'UI (routes du front servies par index.html, comme aujourd'hui) ;
    • /api/ → api:8000 ;
    • WHEP (/\<chemin>/whep, et requêtes WHEP associées : PATCH, DELETE sur la session) → mediamtx:8889 ;
    • HLS (/\<chemin>/index.m3u8 et segments LL-HLS) → mediamtx:8888, sans mise en tampon (LL-HLS) ;
    • le choix exact des préfixes (par ex. /flux/whep/…, /flux/hls/…) est laissé au ticket, tant que l'UI n'utilise que des URL relatives.
  • Ports publiés : 443 (HTTPS) ; 80 et 8080 (redirection 301 vers https://\<même hôte>\<même chemin>, sauf /argos-ca.crt) ; 8189/udp (média WebRTC, déjà chiffré en DTLS-SRTP) ; 8554 (RTSP, inchangé jusqu'à la 0.6.2). Ne sont plus publiés : 8000, 8888, 8889. Les ports 80 et 8080 sont réglables par .env.
  • Front : URL_API, whep.ts, hls.ts construisent des URL relatives à l'origine de la page ; VITE_ARGOS_PORT_API et les ports 8888 / 8889 codés en dur disparaissent.
  • Cookie : Secure; HttpOnly; SameSite=Lax, à la pose comme à la suppression. Aucun réglage pour retirer Secure.
  • CORS : CORSMiddleware et ARGOS_ORIGINES_AUTORISEES supprimés (compose, .env.example, configuration, doc).
  • Filtre « sortie seulement » (ADR 0003) : conservé tel quel ; l'API reste joignable du seul réseau Compose (via web) et du healthcheck.
  • Service certificats (ponctuel, restart: "no", image légère avec openssl ; web en depends_on … condition: service_completed_successfully) :
    • Volume autorite (clé + certificat de l'Autorité), monté seulement dans certificats.
    • Volume certificats-serveur (certificat serveur, sa clé, partie publique de l'Autorité), écrit par certificats, monté en lecture seule dans web ; api ne reçoit que le certificat serveur (public/serveur.crt, sans clé), pour reconnaître l'hôte du Site parmi les Candidats.
    • Autorité absente → générée (10 ans). Jamais régénérée si présente.
    • Certificat serveur : signé par l'Autorité, 397 jours, SAN = localhost, 127.0.0.1 et chaque entrée de MTX_WEBRTCADDITIONALHOSTS (IP du Site déjà déclarée pour WebRTC). Régénéré si absent, si ses SAN diffèrent de ceux attendus, ou s'il lui reste moins de 30 jours.
    • Affiche l'empreinte SHA-256 de l'Autorité dans ses logs.
  • Certificat fourni : si ARGOS_CERTIFICAT_DOSSIER (.env) pointe vers un dossier contenant certificat.crt et cle.key, certificats les copie tels quels pour web, ne génère rien, et /argos-ca.crt répond 404.
  • /argos-ca.crt : servi par nginx sur les ports HTTP (et HTTPS), type application/x-x509-ca-cert, partie publique de l'Autorité seulement.
  • lancer-argos.command : ouvre https://localhost ; affiche l'empreinte de l'Autorité ; si elle n'est pas dans le trousseau de session, demande (o/n) puis security add-trusted-cert (macOS demande le mot de passe). Ne redemande pas si elle y est déjà.
  • Dev (Vite) : server.https avec le certificat serveur d'ArgOS (lu depuis le volume ou un export local), et server.proxy vers la stack pour /api et les Flux ; même origine qu'en prod. Le port 5173 reste.
  • Tests : tests/stack_compose.py et tests/web/conftest.py passent par https://localhost en validant le certificat contre l'Autorité du Site (pas de verify=False).
  • Doc :
    • docs/dev/schema-flux.md déplacé vers docs/features/reseau/schema-flux.md, mis à jour pour la 0.6.1 (proxy, ports fermés, chaque flux marqué chiffré ou en clair) ; liens corrigés (docs/cameras/reseau-et-detection.md, docs/cameras/ajouter-une-camera.md, docs/specs/v0.4.0-detection-des-cameras.md) ; docs/features/index.md y renvoie.
    • Nouvelle page : installer l'Autorité du Site (macOS, iOS, Windows, Android ; empreinte ; certificat fourni ; perte du volume).
    • docs/securite.md : § « deux origines, CORS » remplacé par « une origine HTTPS » ; accès à la clé de l'Autorité (hôte = confiance totale ; clé montée dans certificats seul ; web compromis = clé serveur de cette machine, 397 jours) ; ligne « Pas de HTTPS » retirée des dettes ; RTSP 8554 en clair noté jusqu'à la 0.6.2.
    • README : adresse https://…, installation de l'Autorité.
    • ADR 0005 — HTTPS par une origine unique et une Autorité du Site (alternatives : TLS par service, Caddy tls internal, auto-signé, Let's Encrypt seul).
  • agents/roles.yml inchangé.

Testing Decisions​

  • Un bon test vérifie un comportement observable depuis l'hôte ou le navigateur : réponse HTTP(S), certificat présenté, en-têtes, écran. Jamais la configuration nginx ou openssl en elle-même.
  • tests/api/ (stack), prior art : tests/stack_compose.py, tests existants de connexion :
    • le certificat présenté par https://localhost se valide contre l'Autorité du Site et couvre localhost, 127.0.0.1 et l'IP déclarée ;
    • http://localhost:8080/… et http://localhost:80/… → 301 vers https://… même chemin ; /argos-ca.crt servi en HTTP, identique à l'Autorité ;
    • cookie de session : Secure, HttpOnly, SameSite=Lax ;
    • localhost:8000, :8888, :8889 ne répondent plus ;
    • connexion, API, WHEP (offre SDP acceptée) et HLS (playlist d'une Caméra simulée H.265) passent par l'origine HTTPS ;
    • plus d'en-tête Access-Control-Allow-Origin ;
    • tous les tests existants passent par l'origine HTTPS.
  • tests/scripts/ (ou test-root adaptée), service certificats : Autorité créée si absente et gardée sinon ; certificat serveur régénéré si l'IP déclarée change ou s'il expire dans moins de 30 jours, gardé sinon ; certificat fourni copié tel quel, sans Autorité.
  • tests/web/ : le parcours connexion → Administration → Live marche en HTTPS (prior art : test_administration.py).
  • Tests humains : installer l'Autorité sur le Mac hôte (via lancer-argos.command) et sur un iPhone, comparer l'empreinte, cadenas sans avertissement dans Safari et Chrome, connexion, Live H.264 et H.265, redirection depuis http://…:8080.

Out of Scope​

  • Authentification des Flux MediaMTX, RTSP 8554 laissé ouvert et en clair (0.6.2).
  • HTTPS d'ArgOS vers les caméras, ONVIF en HTTP (0.6.3).
  • HSTS.
  • Sauvegarde ou export de l'Autorité du Site.
  • Renouvellement automatique d'un certificat fourni par l'Administrateur (Let's Encrypt, ACME).
  • Images versionnées et compose de prod (0.7.0).

Changements apportés aux versions antérieures​

VersionÉlémentAvantAprèsÀ annoter
0.2.0Accès à l'APIHTTP sur le port 8000, publié sur l'hôteHTTPS sous l'origine unique (/api), 8000 non publiév0.2.0, #6
0.2.0Cookie de sessionHttpOnly; SameSite=Lax, sans SecureSecure; HttpOnly; SameSite=Laxv0.2.0, #6
0.3.0Adresse de l'UIhttp://\<hôte>:8080https://\<hôte> ; 8080 redirige vers HTTPSv0.3.0, #12
0.3.0Origines et CORSUI et API sur deux origines, CORS avec credentials, ARGOS_ORIGINES_AUTORISEESUne seule origine, plus de CORS ni de variablev0.3.0, #12
0.3.0Live WebRTC (WHEP)http://\<hôte>:8889/…/whepsous l'origine HTTPS, 8889 non publiév0.3.0, #12
0.5.0Live HLS (H.265)http://\<hôte>:8888/…/index.m3u8sous l'origine HTTPS, 8888 non publiév0.5.0, #45

Further Notes​

  • WebRTC chiffrait déjà le média (DTLS-SRTP) ; seule la signalisation WHEP passait en clair.
  • MTX_WEBRTCADDITIONALHOSTS sert désormais aussi aux noms du certificat serveur : sans IP déclarée, le Site n'est joignable en HTTPS valide que depuis localhost.
  • Contexte : feuille de route de dev (section 0.6.1), docs/securite.md, docs/features/reseau/schema-flux.md, ADR 0001, 0003, 0004.