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 deweb, sur le port443(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 porteSecure, 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://localhostsans 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
- 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. - En tant qu'Administrateur, je veux que mon ancienne adresse
http://\<IP du Site>:8080me redirige vers HTTPS, pour ne pas avoir à changer mes habitudes ni mes favoris. - 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://. - 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.
- 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
- 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.
- 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. - En tant qu'Administrateur, je veux une doc pas à pas pour installer l'Autorité sur macOS, iOS, Windows et Android.
- En tant qu'Administrateur, je veux que
lancer-argos.commandme 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. - En tant qu'Administrateur, je veux que le changement d'IP du Site (nouveau bail DHCP,
.envmis à jour) régénère le certificat serveur sans me faire réinstaller l'Autorité sur mes postes. - En tant qu'Administrateur, je veux que le certificat serveur se renouvelle seul avant d'expirer.
- 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
- 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
- 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
Securecompris, Safari compris).
Documentation
- 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.
- 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 (RTSP8554, 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 sur443dans le conteneur, publié sur$\{ARGOS_PORT_HTTPS:-443\}. Routes :/→ fichiers statiques de l'UI (routes du front servies parindex.html, comme aujourd'hui) ;/api/→api:8000;- WHEP (
/\<chemin>/whep, et requêtes WHEP associées :PATCH,DELETEsur la session) →mediamtx:8889; - HLS (
/\<chemin>/index.m3u8et 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) ;80et8080(redirection 301 vershttps://\<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 ports80et8080sont réglables par.env. - Front :
URL_API,whep.ts,hls.tsconstruisent des URL relatives à l'origine de la page ;VITE_ARGOS_PORT_APIet les ports8888/8889codés en dur disparaissent. - Cookie :
Secure; HttpOnly; SameSite=Lax, à la pose comme à la suppression. Aucun réglage pour retirerSecure. - CORS :
CORSMiddlewareetARGOS_ORIGINES_AUTORISEESsupprimé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 ;webendepends_on … condition: service_completed_successfully) :- Volume
autorite(clé + certificat de l'Autorité), monté seulement danscertificats. - Volume
certificats-serveur(certificat serveur, sa clé, partie publique de l'Autorité), écrit parcertificats, monté en lecture seule dansweb;apine 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.1et chaque entrée deMTX_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.
- Volume
- Certificat fourni : si
ARGOS_CERTIFICAT_DOSSIER(.env) pointe vers un dossier contenantcertificat.crtetcle.key,certificatsles copie tels quels pourweb, ne génère rien, et/argos-ca.crtrépond404. /argos-ca.crt: servi par nginx sur les ports HTTP (et HTTPS), typeapplication/x-x509-ca-cert, partie publique de l'Autorité seulement.lancer-argos.command: ouvrehttps://localhost; affiche l'empreinte de l'Autorité ; si elle n'est pas dans le trousseau de session, demande (o/n) puissecurity add-trusted-cert(macOS demande le mot de passe). Ne redemande pas si elle y est déjà.- Dev (Vite) :
server.httpsavec le certificat serveur d'ArgOS (lu depuis le volume ou un export local), etserver.proxyvers la stack pour/apiet les Flux ; même origine qu'en prod. Le port5173reste. - Tests :
tests/stack_compose.pyettests/web/conftest.pypassent parhttps://localhosten validant le certificat contre l'Autorité du Site (pas deverify=False). - Doc :
docs/dev/schema-flux.mddéplacé versdocs/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.mdy 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 danscertificatsseul ;webcompromis = clé serveur de cette machine, 397 jours) ; ligne « Pas de HTTPS » retirée des dettes ; RTSP8554en 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.ymlinchangé.
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://localhostse valide contre l'Autorité du Site et couvrelocalhost,127.0.0.1et l'IP déclarée ; http://localhost:8080/…ethttp://localhost:80/…→301vershttps://…même chemin ;/argos-ca.crtservi en HTTP, identique à l'Autorité ;- cookie de session :
Secure,HttpOnly,SameSite=Lax; localhost:8000,:8888,:8889ne 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.
- le certificat présenté par
tests/scripts/(ou test-root adaptée), servicecertificats: 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 depuishttp://…:8080.
Out of Scope
- Authentification des Flux MediaMTX, RTSP
8554laissé 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ément | Avant | Après | À annoter |
|---|---|---|---|---|
| 0.2.0 | Accès à l'API | HTTP sur le port 8000, publié sur l'hôte | HTTPS sous l'origine unique (/api), 8000 non publié | v0.2.0, #6 |
| 0.2.0 | Cookie de session | HttpOnly; SameSite=Lax, sans Secure | Secure; HttpOnly; SameSite=Lax | v0.2.0, #6 |
| 0.3.0 | Adresse de l'UI | http://\<hôte>:8080 | https://\<hôte> ; 8080 redirige vers HTTPS | v0.3.0, #12 |
| 0.3.0 | Origines et CORS | UI et API sur deux origines, CORS avec credentials, ARGOS_ORIGINES_AUTORISEES | Une seule origine, plus de CORS ni de variable | v0.3.0, #12 |
| 0.3.0 | Live WebRTC (WHEP) | http://\<hôte>:8889/…/whep | sous l'origine HTTPS, 8889 non publié | v0.3.0, #12 |
| 0.5.0 | Live HLS (H.265) | http://\<hôte>:8888/…/index.m3u8 | sous 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_WEBRTCADDITIONALHOSTSsert désormais aussi aux noms du certificat serveur : sans IP déclarée, le Site n'est joignable en HTTPS valide que depuislocalhost.- Contexte : feuille de route de dev (section 0.6.1),
docs/securite.md,docs/features/reseau/schema-flux.md, ADR 0001, 0003, 0004.