{
  "_zweck": "Eine Quelle fuer alle Antwort-Header. Der Worker (src/worker.ts) setzt sie auf seine Antworten, scripts/headers.mjs schreibt daraus build/site/_headers fuer die Assets, die ohne Worker ausgeliefert werden (Cloudflare wendet _headers nicht auf Worker-Antworten an). Jede CSP-Ausnahme traegt ihr 'warum'.",
  "global": {
    "X-Content-Type-Options": { "wert": "nosniff", "warum": "kein MIME-Sniffing, gerade bei .wasm/.js aus fremden Paketen" },
    "Referrer-Policy": { "wert": "same-origin", "warum": "Werkzeugpfade gehen nie an fremde Seiten, auf die eine Sammlung verlinkt" },
    "X-Frame-Options": { "wert": "SAMEORIGIN", "warum": "Altbrowser ohne frame-ancestors; Rahmen-UI bettet nur dieselbe Origin ein" },
    "Cross-Origin-Opener-Policy": { "wert": "same-origin", "warum": "BentoPDF verlangt Cross-Origin-Isolation (eigenes _headers); muss auch fuer die spaetere Rahmenseite gelten, die BentoPDF im iframe zeigt" },
    "Cross-Origin-Embedder-Policy": { "wert": "credentialless", "warum": "wie BentoPDF-Original; ohne Fremd-Hosts fuer IT-Tools und CyberChef folgenlos" },
    "Cross-Origin-Resource-Policy": { "wert": "same-origin", "warum": "Assets sollen nicht von fremden Seiten eingebunden werden" },
    "Permissions-Policy": { "wert": "geolocation=(), payment=(), usb=(), camera=(self), microphone=(self), interest-cohort=()", "warum": "camera/microphone nur fuer IT-Tools (Kamera-Rekorder, QR-Scanner) und nur eigene Origin" }
  },
  "csp_basis": {
    "default-src": { "werte": ["'self'"], "warum": "Grundsatz: nur eigene Origin" },
    "connect-src": { "werte": ["'self'"], "warum": "kein fetch/XHR/WebSocket an Fremd-Hosts" },
    "img-src": { "werte": ["'self'", "data:"], "warum": "Inline-Icons als data:-URL" },
    "object-src": { "werte": ["'none'"], "warum": "keine Plugins" },
    "base-uri": { "werte": ["'self'"], "warum": "<base> nur auf eigene Origin (Worker setzt /it-tools/)" },
    "form-action": { "werte": ["'self'"], "warum": "keine Formular-Posts nach aussen" },
    "frame-ancestors": { "werte": ["'self'"], "warum": "nur die eigene Rahmen-UI darf einbetten" }
  },
  "csp_sammlung": {
    "/it-tools/": {
      "script-src": { "werte": ["'self'", "'unsafe-inline'", "'unsafe-eval'", "'wasm-unsafe-eval'", "blob:"], "warum": "index.html hat ein Inline-Script ohne Hash-Stabilitaet ueber Updates; 9 Bundles nutzen eval/new Function; WASM (age, re2, tree-sitter, Tesseract, ONNX); Worker aus blob:" },
      "worker-src": { "werte": ["'self'", "blob:"], "warum": "Workbox-Service-Worker und Web Worker aus blob:" },
      "style-src": { "werte": ["'self'", "'unsafe-inline'"], "warum": "Naive UI setzt Styles zur Laufzeit (CSS-in-JS)" },
      "img-src": { "werte": ["'self'", "data:", "blob:"], "warum": "erzeugte Bilder (QR, Konverter) als blob:/data:" },
      "font-src": { "werte": ["'self'", "data:"], "warum": "mitgelieferte Schriften, teils als data:" },
      "media-src": { "werte": ["'self'", "blob:", "data:"], "warum": "Beep.mp3, Kamera-/Audio-Werkzeuge" },
      "connect-src": { "werte": ["'self'", "blob:", "data:"], "warum": "fetch auf lokal erzeugte blob:/data:-URLs, kein Fremd-Host" }
    },
    "/cyberchef/": {
      "script-src": { "werte": ["'self'", "'unsafe-inline'", "'unsafe-eval'", "'wasm-unsafe-eval'", "blob:"], "warum": "CyberChef_v11.5.0.html hat zwei Inline-Scripts; 25 Bundles nutzen eval/new Function; WASM in Operationen; Worker aus blob:" },
      "worker-src": { "werte": ["'self'", "blob:"], "warum": "ChefWorker, InputWorker u.a." },
      "style-src": { "werte": ["'self'", "'unsafe-inline'"], "warum": "Inline-Styles in der Oberflaeche" },
      "img-src": { "werte": ["'self'", "data:", "blob:"], "warum": "Ausgabe als Bild (Render Image u.a.)" },
      "font-src": { "werte": ["'self'", "data:"], "warum": "mitgelieferte Schriften" },
      "connect-src": { "werte": ["'self'", "blob:", "data:"], "warum": "Datei-Laden ueber blob:; 'Show on map' (unpkg, OSM) faellt absichtlich weg" }
    },
    "/pdf/": {
      "script-src": { "werte": ["'self'", "'wasm-unsafe-eval'", "'unsafe-eval'", "blob:"], "warum": "aus BentoPDFs eigenem _headers ohne jsDelivr: PyMuPDF/Pyodide, Ghostscript, CPDF, Tesseract" },
      "worker-src": { "werte": ["'self'", "blob:"], "warum": "wie BentoPDF-Original" },
      "style-src": { "werte": ["'self'", "'unsafe-inline'"], "warum": "wie BentoPDF-Original, ohne fonts.googleapis.com" },
      "img-src": { "werte": ["'self'", "data:", "blob:"], "warum": "Seitenvorschauen als blob:; BentoPDF erlaubt https: -- hier nicht" },
      "font-src": { "werte": ["'self'", "data:"], "warum": "Schriften lokal unter /pdf/wasm/; ohne fonts.gstatic.com und githack" },
      "connect-src": { "werte": ["'self'", "blob:"], "warum": "ohne jsDelivr, CORS-Proxy und githack; Signieren mit Zeitstempel (TSA) geht damit nicht" },
      "frame-src": { "werte": ["'self'", "blob:"], "warum": "PDF-Vorschau im iframe (pdfjs-viewer, blob:)" }
    }
  }
}
