API-Keys werden via electron.safeStorage verschlüsselt gespeichert.
| Betriebssystem | Mechanismus | Schutz |
|---|---|---|
| macOS | macOS Keychain | Nur eingeloggter User + diese App-Identität |
| Windows | DPAPI (Data Protection API) | Nur eingeloggter Windows-User |
| Linux | libsecret / kwallet | Desktop-Session-Key |
function encryptKey(str) {
if (!safeStorage.isEncryptionAvailable()) return { v: str }; // Fallback: Plaintext
return { v: safeStorage.encryptString(str).toString('base64'), enc: true };
}
function decryptKey(entry) {
if (!entry) return null;
if (!entry.enc) return entry.v; // Plaintext-Fallback oder Legacy
try { return safeStorage.decryptString(Buffer.from(entry.v, 'base64')); }
catch { return null; }
}{
"enc": true,
"keys": {
"gemini": "BASE64_CIPHERTEXT",
"openai": "BASE64_CIPHERTEXT"
}
}Der Ciphertext ist ohne den OS-Keychain-Key nicht entschlüsselbar. Ein einfaches cat ai-key.json zeigt nur Base64-Daten.
macOS: ~/Library/Application Support/cdp-analyzer/ai-key.json
Windows: %APPDATA%\cdp-analyzer\ai-key.json
Linux: ~/.config/cdp-analyzer/ai-key.json
Wenn safeStorage.isEncryptionAvailable() false zurückgibt (z.B. headless CI/CD), wird Plaintext gespeichert — mit enc: false markiert. Das passiert in normalen Desktop-Umgebungen nicht.
Ältere Versionen speicherten Plaintext im Legacy-Feld data.key. Beim ersten ai:loadKey-Aufruf wird dieses Feld noch unterstützt, aber beim nächsten Speichern wird es gelöscht und durch verschlüsselte Keys ersetzt.
webPreferences: {
contextIsolation: true, // Renderer kann Node.js nicht direkt nutzen
nodeIntegration: false, // window.require() ist nicht verfügbar
}Nur explizit in preload.js / preload-ai.js exponierte Funktionen sind aus dem Renderer erreichbar:
contextBridge.exposeInMainWorld('cdp', {
getTargets: () => ipcRenderer.invoke('cdp:getTargets'),
connect: (url) => ipcRenderer.invoke('cdp:connect', url),
// ... nur explizit genannte Funktionen
});Der Renderer hat keinerlei Zugriff auf:
- Das Dateisystem
- Node.js-Module
- Electron-interne APIs
- Andere IPC-Kanäle als die exponierten
- Nur zu
localhost:9222— kein Remote-Zugriff möglich - Chrome muss explizit mit
--remote-debugging-port=9222laufen; der Splash-Screen kann diesen Start lokal auslösen - Die App verbindet sich NUR auf expliziten Nutzer-Request (Tab-Auswahl + Verbinden-Button)
Gesendet werden:
- Der Nutzer-Prompt
- Aktive Context-Daten (je nach ausgewählten Pills):
- API-Requests: URL, Methode, Status, Headers (ohne rohe Token-Strings), JWT-Payload (decodiert, ohne Signatur)
- Network: URL, Methode, Status, Typ
- Console: Log-Texte
- Errors: URL, Status, Fehlertext
Nicht gesendet:
- Rohe Bearer-Tokens / API-Keys aus Headers
- Response-Bodies (außer wenn Agent explizit
getResponseBodyaufruft) - Cookies
- Passwörter
Wenn der Agent dieses Tool aufruft, wird der Response-Body in der Antwort an die KI-API gesendet. Das ist bewusst — der Nutzer hat dieses Tool aktiviert damit der Agent API-Daten analysieren kann.
- Nur eigene Browser-Sessions debuggen — CDP hat vollen Zugriff auf den Tab inkl. aller Daten
- Deep Intercept nur wenn nötig — pausiert alle Requests, leichte Verlangsamung
- API-Keys nach Verdacht rotieren — OpenAI unter platform.openai.com/api-keys
- Chrome-Profil isolieren —
--user-data-dirauf ein dediziertes Verzeichnis setzen, nicht das Standard-Profil verwenden