Sécurité & confidentialité

Sécurité de l'appareil Twoody

Les protections qui tournent sur l'enceinte elle-même, au-delà du cloud.

Le firmware est auditable, les fichiers de configuration sont verrouillés à un seul processus, l'appairage est protégé par un code court à usage unique, et chaque cycle de mise à jour passe par un kill switch côté serveur. Un admin peut aussi pousser une mise à jour forcée sur un appareil unique si un correctif critique doit atterrir rapidement — le kill switch global reste prioritaire.

Mises à jour vérifiées

Les mises à jour logicielles (OTA) passent par un kill switch côté serveur et, en mode renforcé, par une vérification de signature cryptographique avant installation. Une compromission de notre dépôt ne peut pas pousser de code non signé sur les appareils en mode strict.

Configuration verrouillée

Le fichier de configuration contenant vos jetons sur l'appareil est en permissions 600, c'est-à-dire lisible uniquement par le processus Twoody — et jamais par les autres processus locaux.

Épinglage de certificat (opt-in)

Pour les déploiements professionnels, l'appareil peut être configuré pour n'accepter que les certificats émis par les autorités racines de Let's Encrypt, fermant la porte à une AC rogue.

Appairage à code court

L'appairage d'un appareil passe par un code à usage unique, à durée limitée, et limité en tentatives. Un tiers qui tenterait de se faire appairer se heurte à un blocage quasi-immédiat.

Kill switch global

Une seule variable d'env (TWOODY_DEVICE_UPDATES_BLOCKED=true) arrête l'OTA nocturne sur la totalité du parc. Si nous détectons une régression sur une release déjà coupée, nous bloquons la propagation instantanément sans rien déployer sur les appareils.

Force-update admin

Un admin peut marquer un appareil unique comme devant faire une mise à jour immédiate — l'appareil poll ce flag sur une boucle courte et applique la mise à jour hors cycle normal, en affichant un overlay « mise à jour ». Le flag se nettoie automatiquement en cas de succès ou de rollback.

Rollback en cas d'échec

Si une mise à jour échoue aux health checks après installation, l'appareil rollback sur le SHA précédent fonctionnel et remonte une télémétrie rolled_back. Nous voyons combien d'appareils ont rollback par release et pouvons bloquer toute promotion qui n'atterrit pas proprement.

Télémétrie OTA

Chaque résultat de mise à jour est reporté via POST /devices/:device_id/update_events avec from_sha et to_sha. L'admin voit un historique par appareil — nous connaissons l'état firmware de chaque appareil sans avoir à faire remonter de données secrètes.

Isolation par appareil (« blast radius limité »)

Chaque appareil de la flotte tire les mises à jour avec une clé d'accès dédiée et en lecture seule, scopée au seul dépôt firmware. Aucun appareil ne peut écrire dans nos dépôts ni accéder à nos autres projets. Si un appareil est compromis (vol, malware, accès physique), la portée se limite à cet appareil — il ne peut pas pousser de code malveillant qui serait ensuite tiré par le reste de la flotte.

Plongée technique

Cycle de vie de l'OTA

L'appareil poll GET /devices/:id/update_check sur une boucle courte. Le serveur renvoie trois informations : un flag blocked global (le kill switch), un plancher min_sha informatif, et un flag force_update par appareil.

La nuit de mise à jour, l'appareil vérifie blocked en premier — si true, le cycle est sauté intégralement. Sinon, il lance auto-update.sh qui fait git-fetch, tourne les tests contre une suite known-good, et swap le firmware atomiquement. Chaque résultat (succeeded, failed, rolled_back) est reporté via POST /devices/:device_id/update_events avec from_sha et to_sha, donc l'état du parc est visible par appareil dans l'admin.

Appairage

Les codes d'appairage font 6 chiffres, expirent après 10 minutes, et ne peuvent être validés qu'une poignée de fois avant d'être invalidés. Chaque tentative est limitée au CDN (10 par 15 min par IP). Un tiers qui a une proximité physique avec votre appareil ne peut quand même pas compléter l'appairage sans votre compte — le code est généré sur votre session authentifiée et lié à votre utilisateur.

Une fois appairé, l'appareil reçoit un bearer X-User-Token comme n'importe quel autre client. Le désappairage révoque ce jeton comme n'importe quelle autre session — l'appareil devient un presse-papiers vis-à-vis de notre API jusqu'à ce que quelqu'un le ré-appaire.

Tunables et settings runtime

Chaque appareil poll GET /admin/devices/:device_id/settings.json toutes les 5 minutes pour les tunables runtime (agressivité VAD, mode Whisper, voix OpenAI, fenêtres de rétention, mode d'enrôlement). Le endpoint est authentifié avec le propre X-User-Token de l'appareil.

Nous fusionnons de manière autoritaire trois couches à la lecture — défauts du schéma → défauts fleet du foyer → overrides par appareil — pour que l'appareil obtienne toujours un snapshot cohérent. Un admin peut régler un appareil seul, un foyer, ou rouler un nouveau défaut sur tout le parc sans redéployer.

L'objectif : aucun single point of failure — un commit rogue, un pipeline de build compromis, une mauvaise nuit de release — ne peut bricker ni backdoorer un appareil à la maison. Le kill switch est toujours à un toggle près, et chaque résultat est visible en télémétrie en quelques minutes.

Sujets liés