Sicherheit und Datenschutz
JuStAI hat Zugriff auf Kameras, Mikrofone und persönliche Informationen. Die GrundsÀtze: lokal zuerst, minimale Rechte, nichts Stilles (Cloud-Fallbacks und sicherheitsrelevante Aktionen werden protokolliert), deterministische Regeln statt Modellentscheidungen bei Ausgabe und Rechten.
Netzwerk und Container
Abschnitt betitelt âNetzwerk und Containerâ| MaĂnahme | Umsetzung |
|---|---|
| Zwei Ports nach auĂen | core:8080 (HTTP, UI/API) und core:8443 (HTTPS, gleiche Anwendung, fĂŒr die GerĂ€te-App). Postgres, go2rtc und Sandbox sind von auĂen nicht erreichbar. |
| Datenbanknetz intern | db ist internal: true |
| Sandbox ohne Netz | sandbox ist internal: true: kein Internet, kein LAN, nur der Core. GeprĂŒft: Postgres, go2rtc, LAN und Internet sind aus der Sandbox nicht erreichbar. |
| Sandbox gehÀrtet | read-only Root-FS, tmpfs /tmp, cap_drop: ALL, no-new-privileges, pids/mem/cpu-Limits, eigener UID (10002), rlimits pro Plugin-Prozess |
| Core ohne Root | UID 10001 |
| go2rtc ohne Zugangsdaten auf Platte | Streams werden zur Laufzeit im Speicher angelegt (PATCH /api/streams), go2rtc.yaml ist read-only gemountet und enthÀlt keine Kameras |
| Talkback-Endpunkt | /internal/talkback/<zufĂ€lliges Token>.wav, Token pro Lautsprecher, nur fĂŒr go2rtc gedacht |
FĂŒr den Zugriff aus dem Internet: JuStAI nicht direkt freigeben, sondern ĂŒber VPN
(z. B. WireGuard) oder einen Reverse-Proxy mit TLS. Dann JUSTAI_PUBLIC_URL auf
https://⊠setzen, damit Cookies als Secure markiert werden.
HTTPS mit lokaler Zertifizierungsstelle
Abschnitt betitelt âHTTPS mit lokaler ZertifizierungsstelleâFĂŒr die GerĂ€te-App (Mikrofon und Kamera im Browser) spricht der Core auf Port
8443 HTTPS (backend/src/justai/tls.py):
- Beim ersten Start entsteht in
/data/tlseine eigene Zertifizierungsstelle (ECDSA P-256, 10 Jahre,pathLen 0). Ihr privater SchlĂŒssel verlĂ€sst den Container nicht (Datei0600) und gehört zur Datensicherung. - Das Serverzertifikat enthĂ€lt
localhost,127.0.0.1,justai.local,JUSTAI_TLS_NAMESund die in der UI hinzugefĂŒgten Adressen; Laufzeit 825 Tage (Apple-Grenze), automatische Neuausstellung 30 Tage vor Ablauf bzw. wenn sich die Namen Ă€ndern. Neue Adressen werden ohne Neustart geladen. GET /api/tls/ca.crt(öffentlich, nur das CA-Zertifikat),GET /api/tls/statusundPOST /api/tls/names(nur Admins). Der SHA-256-Fingerabdruck steht in der Admin-UI zum Vergleich auf dem GerĂ€t.- Wer das CA-Zertifikat installiert, vertraut damit allen Zertifikaten, die
diese CA ausstellt. Deshalb: CA-SchlĂŒssel nicht weitergeben, Zertifikat nur auf
eigenen GerÀten installieren.
JUSTAI_TLS_ENABLED=falseschaltet HTTPS ab.
Gekoppelte GerĂ€te-Apps authentisieren sich mit ihrem zufĂ€lligen Token (im Core nur der Hash). Ein Browser-GerĂ€t kann nur Display-, Audio- und Kamera-FĂ€higkeiten anmelden. Medien laufen nur ĂŒber die Verbindung des gekoppelten GerĂ€ts.
Authentifizierung (Admin-UI/API)
Abschnitt betitelt âAuthentifizierung (Admin-UI/API)â- Passwörter: Argon2id (argon2-cffi), Rehash bei geĂ€nderten Parametern; MindestlĂ€nge 8.
- Initiales Admin-Passwort: zufÀllig erzeugt, nur in
/data/initial_admin_password.txtund einmal im Log (oder perJUSTAI_ADMIN_PASSWORDgesetzt). - Sitzungen: JWT (HS256, SchlĂŒssel aus dem Master-Key abgeleitet), als
HttpOnly-,SameSite=Strict-Cookie oder als Bearer-Token. Ăberall abmelden erhöht die Token-Version des Benutzers und macht alle alten Tokens ungĂŒltig. - CSRF: Schreibende Anfragen brauchen den Header
x-justai: 1. Ein fremdes Formular kann ihn nicht ohne CORS-Preflight setzen; CORS ist standardmĂ€Ăig aus. - Brute-Force-Schutz: Nach 5 Fehlversuchen in 15 Minuten wird pro Benutzername
und pro Client-Adresse gesperrt: zuerst 30 s, dann verdoppelt bis 15 min.
Fehlversuche stehen im Audit-Log (
auth.login_failed). - Security-Header fĂŒr alle Antworten: Content-Security-Policy (Skripte nur vom
eigenen Server, keine Fremd-Frames),
X-Frame-Options: DENY,X-Content-Type-Options: nosniff,Referrer-Policy: no-referrer.
Rollen und Rechte
Abschnitt betitelt âRollen und RechteâRollen admin, resident, guest (auth/rbac.py), Rechtevokabular aus dem SDK.
Gesprochene GesprÀche sind nicht authentifiziert. Eine Session bekommt die
default_role ihres Endpoints (Standard resident; an öffentlich zugÀnglichen
Orten auf guest setzen). Eine erkannte Person kann die Rechte höchstens auf
resident anheben. Biometrie gewÀhrt nie administrative Rechte:
system.manage, devices.manage, identity.manage, devices.provide und
ai.provide sind in GesprÀchen grundsÀtzlich ausgeschlossen.
Bewohner dĂŒrfen GerĂ€te per Sprache bedienen (devices.control: PrivatsphĂ€re-Modus,
Zuhörpause, Neu verbinden, Testton), aber nicht hinzufĂŒgen oder konfigurieren. GĂ€ste
dĂŒrfen beides nicht.
Tools deklarieren benötigte Rechte und Nebenwirkungen. Folgenreiche Aktionen
(requires_confirmation) fĂŒhrt der Assistent erst nach einer ausdrĂŒcklichen
BestÀtigung aus: GedÀchtnis löschen, Automation löschen, Gesicht registrieren u. a.
Die BestÀtigung ist an Session und Argumente gebunden, muss in einem spÀteren
Benutzerbeitrag kommen (das Modell kann sich nicht selbst bestÀtigen) und lÀuft ab. Jede
Tool-AusfĂŒhrung wird protokolliert (Parameter redigiert).
Geheimnisse
Abschnitt betitelt âGeheimnisseâsecrets-initerzeugt beim ersten Start DB-Passwort, Master-Key und Sandbox-Token im Volumesecrets(Master-Key nur fĂŒr den Core lesbar, 0400).- Plugin-Secrets (
secret_fields) und GerĂ€tezugangsdaten werden mit Fernet verschlĂŒsselt in der Datenbank gespeichert (SchlĂŒssel aus dem Master-Key). Die API liefert sie nie zurĂŒck, die UI zeigt nur âgesetztâ. - Logs: structlog-Prozessor und
common/redact.pyentfernen bekannte SchlĂŒsselnamen (password, token, api_key, âŠ) und Zugangsdaten in URLs (rtsp://user:pass@ârtsp://***@). - Backups enthalten Secrets und werden mit
chmod 600geschrieben (DEPLOYMENT.md).
Plugins und generierter Code
Abschnitt betitelt âPlugins und generierter Codeâ- Hochgeladene Plugins sind immer
untrusted, laufen in der Sandbox und starten ohne Rechte, bis ein Admin sie gewĂ€hrt (PLUGINS.md). - Netzwerkzugriff nur ĂŒber das Core-Gateway auf die Hosts der Allowlist; private, Loopback-, Link-Local- und Multicast-Adressen sind gesperrt (auch nach DNS-Auflösung).
- Selbst entwickelte Tools (
tools.develop): Code wird statisch geprĂŒft (verbotene Module wieos,subprocess,socket,importlib; verbotene Aufrufe wieeval,exec,open,getattr), in der Sandbox getestet, dann von einem Modell auf Sicherheit geprĂŒft und erst nach Freigabe durch einen Admin aktiviert. Er wird immer einuntrusted-Plugin mit eingeschrĂ€nkter Rechteliste (nie GerĂ€testeuerung, Heimnetz oder Systemeinstellungen). Hintergrundjobs laufen höchstens alle 60 s, höchstens 5 pro Plugin. API-Keys trĂ€gt der Admin ein, sie werden verschlĂŒsselt gespeichert. Der Core selbst wird nie verĂ€ndert. Versionen, Rollback und Deaktivierung in der Admin-UI unter Tools â Entwicklung (PLUGINS.md).
Datenschutz
Abschnitt betitelt âDatenschutzâ| Thema | Umsetzung |
|---|---|
| Cloud-KI | global abschaltbar; pro Rolle local_only/prefer_local/any; getrennte Schalter fĂŒr Kamerabilder, GesprĂ€chsaudio und persönliche Erinnerungen; pro Raum cloud_media_allowed. Die Websuche (Gemini â Google-Suche) ist abschaltbar; ihre Anfragen gehen an Google. Ein Wechsel von lokal zu Cloud wird nie still gemacht: Event ai.provider.fallback und Audit-Eintrag. |
| Sichtbarkeit | Displays zeigen, ob im Raum gerade zugehört oder gesprochen wird und ob ein Cloud-Realtime-Modell aktiv ist. Die Admin-UI zeigt das fĂŒr alle RĂ€ume. |
| Kameras | PrivatsphÀrenzonen werden vor jeder Analyse geschwÀrzt; Vision pro Raum abschaltbar; keine Speicherung von Kamerabildern zu Sichtungen |
| Biometrie | Gesicht und Stimme nur mit dokumentierter Einwilligung (getrennt je Merkmal); Widerruf löscht alle Merkmale dieser Art; Export möglich; Ăhnlichkeitswerte werden nie als Wahrscheinlichkeit dargestellt (VISION.md) |
| GedĂ€chtnis | Herkunft sichtbar, private Erinnerungen nur fĂŒr ihre Person, Vergessen dauerhaft (MEMORY.md) |
| Audio | Es wird kein Audio gespeichert. Ausnahme: ausdrĂŒcklich angeforderte Diagnoseaufnahmen (max. 30 s, Download) |
| Stimmvergleich | FĂŒr âGesprĂ€ch fortsetzen?â wird aus Wakeword und Sprache eines GesprĂ€chs ein Stimm-Fingerabdruck berechnet: nur im Arbeitsspeicher, keiner Person zugeordnet, nach dem Fortsetzungsfenster verworfen; die Sprachdaten selbst werden direkt nach der Berechnung gelöscht. Abschaltbar pro Endpoint (speaker_check). |
| Personenbezogene Ausgaben | nicht auf Displays in gemeinsam genutzten RĂ€umen |
Aufbewahrung
Abschnitt betitelt âAufbewahrungâEinstellbar unter Einstellungen â Aufbewahrung; ein tĂ€glicher Job löscht Ă€ltere Daten:
| Daten | Standard |
|---|---|
| dauerhafte Events | 90 Tage |
| GesprÀchstranskripte | 365 Tage |
| Sichtungen | 60 Tage |
| Tool-Protokoll | 90 Tage |
| Display-Darstellungen | 30 Tage |
| erledigte Jobs | 14 Tage |
Audit-Log
Abschnitt betitelt âAudit-LogâGET /api/audit und Admin-UI â Diagnose â Audit-Log: Anmeldungen und
Fehlversuche, Ănderungen an Benutzern, Plugins (Installation, Rechte), Einstellungen,
GerÀten, Automationen, GedÀchtnis, Biometrie, Cloud-Fallbacks, Netzwerksuche,
PTZ-Tracking, Display-Darstellungen.
Bekannte Grenzen
Abschnitt betitelt âBekannte Grenzenâ- Gesprochene Befehle sind nicht authentifiziert. Wer im Raum spricht, hat die
Rechte des Endpoints. FĂŒr sensible RĂ€ume
default_role: guestwÀhlen. - Gesichtserkennung lÀsst sich mit Fotos tÀuschen (keine Lebenderkennung), Stimmerkennung mit Aufnahmen. Deshalb dienen beide nur der Personalisierung, nie der Autorisierung.
- Die Sandbox ist eine Container-Isolation mit rlimits, keine VM. FĂŒr Code unbekannter Herkunft ist das eine Schutzschicht, kein Freibrief.
- Der Brute-Force-Schutz hĂ€lt seinen Zustand im Speicher; ein Neustart setzt ihn zurĂŒck.