# Security & External Dependency Audit

## Datum: 2026-04-04
## Status: PASS (nach Fixes)

Geprüft auf BMW-Compliance: keine externen Datenverbindungen zur Laufzeit.

---

## Externe Verbindungen — Übersicht

| Typ | Gefunden | Risiko | Status |
|-----|----------|--------|--------|
| Google Fonts (Runtime) | Nein | Hoch | OK |
| Google Fonts (Build-Zeit via `next/font/google`) | **Ja** → behoben | Mittel | **BEHOBEN** |
| CDN Scripts (cdnjs, unpkg, jsdelivr) | Nein | Hoch | OK |
| Analytics / Tracking (GA, Hotjar, Mixpanel, Sentry) | Nein | Hoch | OK |
| Externe Bilder (`<Image src="https://...">`) | Nein | Niedrig | OK |
| Hardcodierte externe URLs im Code | Nein | Hoch | OK |
| Next.js Telemetrie | **Aktiv** → behoben | Mittel | **BEHOBEN** |
| Supabase (Cloud) | Ja | Hoch | Siehe unten |
| Supabase Realtime (WebSocket) | Ja (1 Stelle) | Mittel | Dokumentiert |
| PWA Service Worker | Ja — lokal, kein CDN | Niedrig | OK |
| E-Mail-Versand | Via `email_queue` Tabelle | Niedrig | OK |
| CSP-Header | Nicht konfiguriert | Mittel | Empfehlung |

---

## Behobene Probleme

### 1. `next/font/google` — JetBrains Mono via Google Fonts CDN

**Problem**: `app/layout.tsx` importierte `JetBrains_Mono` aus `next/font/google`.
Next.js lädt diese Schriftart zwar zur Build-Zeit herunter (kein Runtime-Request), aber der
Build-Prozess selbst benötigt eine Verbindung zu `fonts.googleapis.com` und `fonts.gstatic.com`.
In einem air-gapped BMW-Build-Environment schlägt der Build fehl.

**Fix**:
- `import { JetBrains_Mono } from 'next/font/google'` entfernt
- `--font-mono` in `globals.css` auf System-Monospace-Stack gesetzt:
  `ui-monospace, 'SFMono-Regular', 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace`
- `cn()` Import entfernt (war danach unbenutzt)

**Dateien**: `app/layout.tsx`, `app/globals.css`

### 2. Next.js Telemetrie nicht deaktiviert

**Problem**: Next.js sendet standardmäßig anonyme Nutzungstelemetrie an Vercel-Server
(`telemetry.nextjs.org`). In BMW-Netzwerken ist ausgehender Traffic zu externen Diensten
nicht erlaubt.

**Fix**: `NEXT_TELEMETRY_DISABLED=1` in `.env.local` und `.env.example` eingetragen.

---

## Schriftarten — Status

| Schriftart | Quelle | Status |
|------------|--------|--------|
| BMW Group TN Pro (alle Gewichte) | `/public/fonts/` lokal | OK |
| BMW Group TN Condensed Pro (alle Gewichte) | `/public/fonts/` lokal | OK |
| Monospace (Code/Zahlen) | System-Font-Stack (kein Download) | OK |

---

## Supabase — Produktionsstrategie

### Aktueller Stand
- **Endpoint**: `https://${SUPABASE_PROJECT_REF}.supabase.co` (Supabase Cloud, US-hosted)
- **Verbindungstypen**:
  - HTTPS REST (PostgREST) — alle Datenbankoperationen
  - HTTPS Auth — Login, Session-Management
  - WebSocket Realtime — 1 Stelle: `assessment-dashboard.tsx` (Live-Antworten)
  - HTTPS Storage — Supabase-signierte URLs für Datei-Downloads (`qaf-client.tsx`, `import-export-tab.tsx`)

### BMW-Produktion: Erforderliche Migration
Supabase muss auf eine **self-hosted Instanz** oder **BMW-interne Infrastruktur** migriert werden.

**Optionen**:
1. **Supabase Self-Hosted** (Docker/Kubernetes) auf BMW-eigenem Server
2. **Supabase Enterprise** mit BMW Private Cloud Deployment
3. **Direkter PostgreSQL-Ersatz** (PostgREST + GoTrue + S3-kompatibler Storage)

**Aufwand**: Nur `.env`-Variablen müssen geändert werden:
```
NEXT_PUBLIC_SUPABASE_URL=https://supabase.internal.bmw.com
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=...
SUPABASE_SERVICE_ROLE_KEY=...
```
Kein Codechange erforderlich, da alle Supabase-Zugriffe über die abstrahierten
Clients in `lib/supabase/` laufen.

### Supabase Realtime (WebSocket)
- **Fundstelle**: `components/assessment/assessment-dashboard.tsx:154–173`
- **Zweck**: Live-Updates für Assessment-Antworten
- **Verhalten bei self-hosted Supabase**: Realtime läuft auf demselben Server →
  WebSocket bleibt intern, kein externer Traffic

---

## Kein Tracking / keine Analytics

Folgende Dienste wurden **nicht gefunden** (korrekt):
- Google Analytics / gtag
- Hotjar, Mixpanel, Amplitude, Segment
- Sentry, PostHog
- Vercel Analytics / Speed Insights
- Fathom, Plausible

---

## Kein CDN-Script-Loading

Alle JavaScript-Abhängigkeiten kommen aus `node_modules` (npm-Build).
Keine `<script src="https://cdn...">` Tags gefunden.

---

## Service Worker (PWA)

`public/sw.js` — vollständig lokal. Strategie:
- Statische Assets: Cache-first (keine externen Quellen)
- API/Supabase: Network-first mit Cache-Fallback (bleibt auf Supabase-Domain, also intern nach Migration)
- Navigation: Network-first mit `/offline` Fallback

---

## E-Mail-Benachrichtigungen

Keine direkte SMTP-Verbindung aus der App. E-Mails werden als Records in die
`email_queue`-Tabelle geschrieben. Der eigentliche Versand erfolgt durch einen
separaten Supabase Edge Function oder externen Worker.

**Aktion für Produktion**: E-Mail-Versandservice muss BMW-intern sein (kein SendGrid,
Mailgun o.ä. ohne BMW-Freigabe). Den `email_queue`-Worker prüfen.

---

## CSP-Header — Empfehlung

Aktuell keine `Content-Security-Policy` Headers konfiguriert. Nach der Supabase-Migration
auf BMW-interne Infrastruktur sollte in `next.config.mjs` ein strikter CSP gesetzt werden:

```js
async headers() {
  return [{
    source: '/(.*)',
    headers: [{
      key: 'Content-Security-Policy',
      value: [
        "default-src 'self'",
        "connect-src 'self' https://supabase.internal.bmw.com wss://supabase.internal.bmw.com",
        "font-src 'self'",
        "img-src 'self' data: blob:",
        "script-src 'self' 'unsafe-inline' 'unsafe-eval'",
        "style-src 'self' 'unsafe-inline'",
      ].join('; ')
    }]
  }]
}
```

---

## Umgebungsvariablen — vollständige Liste

| Variable | Verwendung | Sichtbarkeit |
|----------|-----------|-------------|
| `NEXT_PUBLIC_SUPABASE_URL` | Supabase-Endpoint | Client + Server |
| `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY` | Supabase Anon Key | Client + Server |
| `SUPABASE_SERVICE_ROLE_KEY` | Admin-Operationen (Server only) | Server only |
| `NEXT_PUBLIC_APP_ENV` | development/staging/production Flag | Client + Server |
| `NEXT_TELEMETRY_DISABLED` | Next.js Telemetrie deaktivieren | Build-Zeit |

---

## Empfehlungen (Priorität)

1. **[ERLEDIGT]** `next/font/google` entfernt → System-Monospace-Stack
2. **[ERLEDIGT]** `NEXT_TELEMETRY_DISABLED=1` gesetzt
3. **[PRODUKTION]** Supabase auf BMW-interne Instanz migrieren (nur `.env` Änderung)
4. **[PRODUKTION]** E-Mail-Queue-Worker auf BMW-interne Infrastruktur prüfen
5. **[OPTIONAL]** CSP-Header in `next.config.mjs` nach Supabase-Migration konfigurieren
6. **[OPTIONAL]** `SUPABASE_SERVICE_ROLE_KEY` nicht in `.env.local` committen — in CI/CD-Secrets verwalten
