
# Audit-Export herunterladen

`GET /v1/audit-exports/{export_id}/download` · Berechtigung `audit-exports:read`

Liefert einen einmalig verwendbaren Link zum Paket eines abgeschlossenen Export-Jobs. API-Schlüssel (geheim oder eingeschränkt) und Dashboard-Benutzer können herunterladen; ein Download im Dashboard erfordert eine kürzliche Anmeldung (Step-up, höchstens 5 Minuten alt). Jeder Aufruf schreibt einen `audit_export.downloaded`-Eintrag in den `admin`-Stream, bevor der Link ausgegeben wird.

## Anfrage

| Parameter | In | Erforderlich | Beschreibung |
|---|---|---|---|
| `export_id` | Pfad | ja | Export-Job-ID mit dem Präfix `aex_`. |

Ein Job, der mit `include_ip: true` erstellt wurde, erfordert außerdem `audit-events:read_ip` beim herunterladenden Schlüssel.

## Antwort

Die Antwort hängt vom `Accept`-Header ab. Beide Formen enthalten `Cache-Control: no-store`, `Referrer-Policy: no-referrer` und `Vary: Accept`, und beide schreiben denselben `audit_export.downloaded`-Eintrag.

- **`Accept` listet `application/json`** (ausdrücklich, mit einem Wert ungleich null bei `q`; `*/*` zählt nicht): `200 OK` mit einem JSON-Body. Verwenden Sie diese Form in einem Browser oder bei jedem Client, der keine Weiterleitung auf eine andere Herkunft lesen kann: Lesen Sie `url` und öffnen Sie ihn dann.

  | Feld | Typ | Beschreibung |
  |---|---|---|
  | `url` | string | Relativer Link auf demselben Host, `/downloads/audit-exports/{environment_id}/{export_id}/{token}`. |
  | `expires_at` | string (date-time) | Zeitpunkt, zu dem der Link nicht mehr funktioniert (15 Minuten nach Ausstellung). |

- **Jeder andere `Accept`**: `302 Found` mit leerem Body. `Location` ist derselbe relative Link.

- Der Link ist 15 Minuten gültig und funktioniert nur einmal: Das Token wird bei der ersten Anfrage verbraucht, auch wenn die Übertragung unterbrochen wird. Rufen Sie diesen Vorgang erneut auf, um einen neuen Link zu erhalten.
- Der Link benötigt keine Zugangsdaten; das Token ist die einzige Berechtigung. Halten Sie `Location` (bzw. `url`) geheim und protokollieren Sie es nicht.
- Die Datei wird im Ruhezustand mit dem Schlüssel der Umgebung verschlüsselt, daher wird keine vorsignierte Speicher-URL verwendet; KeenAuth entschlüsselt sie und streamt sie.

Das Öffnen des Links liefert `200 OK` mit `Content-Type: application/x-tar`, `Content-Length` und `Content-Disposition: attachment; filename="audit-export-aex_….tar"`. Das tar-Paket enthält:

| Datei | Inhalt |
|---|---|
| `records.ndjson.gz` | Jeder Kettendatensatz jeder abgedeckten Stunde in Reihenfolge, ein JSON-Objekt pro Zeile: passende Datensätze vollständig, die übrigen als inhaltslose Platzhalter (`"omitted": true`), damit die Hash-Kette ohne Offenlegung rekonstruiert werden kann. |
| `manifest.json` | Filter, Anzahl, Datei-Hash und je abgedeckter Stunde der signierte Checkpoint und der Inklusionsnachweis; kanonisches JSON (RFC 8785). |
| `manifest.jws` | ES256-Signatur über `manifest.json`; prüfen Sie sie mit den öffentlichen Schlüsseln in `audit-jwks.json`. |

Wenn die Verbindung endet, bevor `Content-Length` Bytes angekommen sind, ist das Paket unvollständig; verwerfen Sie es und fordern Sie einen neuen Link an. Ein ungültiger, bereits verwendeter oder abgelaufener Link liefert `404 not_found`.

## Fehler

Jeder Fehler ist ein `application/problem+json`-Body mit einem stabilen `code`.

| HTTP | `code` | Wann |
|---|---|---|
| 401 | `unauthenticated` | Der API-Schlüssel fehlt, ist ungültig oder wurde widerrufen. |
| 403 | `insufficient_permissions` | Dem Schlüssel fehlt `audit-exports:read`, der Job wurde mit `include_ip` erstellt und dem Schlüssel fehlt `audit-events:read_ip` (`required_permissions` listet beide), oder der Aufrufer ist weder ein API-Schlüssel noch ein Dashboard-Benutzer. |
| 404 | `not_found` | Der Job existiert nicht, gehört zu einer anderen Umgebung oder die ID ist fehlerhaft. Beim Link: Das Token ist ungültig, bereits verwendet oder abgelaufen. |
| 409 | `conflict` | Der Job ist noch nicht abgeschlossen oder seine Datei ist abgelaufen. |
| 429 | `rate_limited` | Das Rate-Limit wurde überschritten; beachten Sie `Retry-After`. |
| 503 | `service_unavailable` | Eine Abhängigkeit ist vorübergehend nicht verfügbar; versuchen Sie es später erneut. |

## Beispiel

```bash
curl -L -o audit-export.tar \
  https://api.eu.keenauth.com/v1/audit-exports/aex_01j9xk3m7q8r2s4t6v8w0y2z4e/download \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
```

Mit `Accept: application/json` wird der Link als JSON statt als Weiterleitung zurückgegeben:

```bash
curl https://api.eu.keenauth.com/v1/audit-exports/aex_01j9xk3m7q8r2s4t6v8w0y2z4e/download \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Accept: application/json"
```

Die SDKs verwenden die JSON-Form und geben `url` und `expires_at` zurück. Die CLI ruft den Link selbst ab, schreibt das Paket in eine Datei (niemals auf die Standardausgabe), verweigert das Überschreiben einer bestehenden Datei und gibt Größe und SHA-256 des Geschriebenen aus:

```bash
keenauth audit-exports download aex_01j9xk3m7q8r2s4t6v8w0y2z4e --file audit-export.tar
```

## Personenbezogene Daten

Dieser Endpunkt verarbeitet personenbezogene Daten: Audit-Ereignisse. [Personenbezogene Daten in den KeenAuth-APIs](/docs/policies/personal-data) beschreibt, was gespeichert wird, wie lange es aufbewahrt wird und wie es gelöscht wird. Senden Sie keine besonderen Kategorien personenbezogener Daten (Gesundheit, biometrische Daten, Religion, politische Meinungen, sexuelle Orientierung) in irgendeinem Feld.
