
# Einen API-Schlüssel erstellen

`POST /v1/api-keys` · Berechtigung `api-keys:write` · erforderlicher `Idempotency-Key`

Erstellt einen Management-API-Schlüssel für die Umgebung. Ein `secret`-Schlüssel hat Zugriff auf die gesamte Management-API; ein `restricted`-Schlüssel enthält nur die aufgelisteten Berechtigungen (`<resource>:<action>`).

- **Rohschlüssel.** Die Antwort enthält `key` genau einmal (`idp_sk_live_…`, `idp_sk_test_…`, `idp_rk_live_…` oder `idp_rk_test_…`). Er kann nicht erneut abgerufen werden; speichern Sie ihn sofort. Die Antwort enthält `Cache-Control: no-store`.
- **Keine Rechteausweitung.** Ein Schlüssel kann keinen Schlüssel erstellen, dessen Berechtigungen über seine eigenen hinausgehen, und ein `restricted`-Schlüssel kann keinen `secret`-Schlüssel erstellen. Der neue Schlüssel kann nicht später ablaufen als der aufrufende Schlüssel; ein aufrufender Schlüssel mit `allowed_cidrs` kann nur Schlüssel mit Netzen erstellen, die innerhalb der eigenen liegen. Wird `allowed_cidrs` weggelassen, erhält der neue Schlüssel die Liste des aufrufenden Schlüssels (`permission_escalation`).
- **Grenzwerte.** Höchstens 50 aktive Schlüssel pro Umgebung, höchstens 20 CIDR-Blöcke pro Schlüssel, Ablauf höchstens 730 Tage in der Zukunft. Ein Schlüssel mit `allowed_cidrs` wird nur aus diesen Netzen akzeptiert.
- **Idempotente Wiederholung.** Wird die Anfrage mit demselben `Idempotency-Key` wiederholt, wird die gespeicherte Antwort ohne Schlüssel erneut ausgegeben: Der Body enthält `secret_redacted: true` und kein `key`. Erstellen Sie einen neuen Schlüssel, wenn der Schlüssel verloren ging.

## Anfrage

Body:

| Feld | Typ | Beschreibung |
|---|---|---|
| `name` | string | Erforderlich. 1–100 Zeichen. |
| `type` | string | Erforderlich. `secret` oder `restricted`. |
| `permissions` | string[] | Für `restricted` erforderlich und nicht leer (höchstens 200); für `secret` weggelassen oder leer. Darf die eigenen Berechtigungen des Aufrufers nicht überschreiten. |
| `expires_at` | string (date-time) | Erforderlich, in der Zukunft, höchstens 730 Tage entfernt. |
| `allowed_cidrs` | string[] | Optional, höchstens 20 CIDR-Blöcke. |

## Antwort

`201 Created` mit `Cache-Control: no-store`. Das Schlüsselobjekt wie in der Listenantwort, zusätzlich `key`.

```json
{
  "id": "key_0000000000000000000000001z",
  "name": "ci",
  "type": "restricted",
  "permissions": ["users:read"],
  "allowed_cidrs": [],
  "last4": "xxxx",
  "created_by": "key_…",
  "created_at": "2026-10-01T10:00:00Z",
  "expires_at": "2027-10-01T10:00:00Z",
  "last_used_at": null,
  "last_used_ip": null,
  "rotated_from": null,
  "revoked_at": null,
  "revoke_reason": null,
  "key": "<shown once>"
}
```

## Fehler

| HTTP | `code` | Wann |
|---|---|---|
| 401 | `unauthenticated` | Der Schlüssel fehlt, ist ungültig oder widerrufen. |
| 403 | `insufficient_permissions` | Dem Schlüssel fehlt die erforderliche Berechtigung. |
| 403 | `permission_escalation` | Die Anfrage würde einem Schlüssel mehr Berechtigungen, einen größeren Netzbereich oder ein späteres Ablaufdatum geben, als der aufrufende Schlüssel hat; ein `restricted`-Schlüssel versucht, über seine eigenen Berechtigungen hinaus zu erstellen, zu rotieren oder zu widerrufen; oder ein anderer Schlüssel versucht, einen im Dashboard erstellten Schlüssel zu rotieren oder zu widerrufen. |
| 409 | `api_key_limit_reached` | Die Umgebung hat bereits das Maximum von 50 aktiven Schlüsseln erreicht. |
| 422 | `validation_failed` | Der Body ist ungültig: `name` fehlt oder ist zu lang, unbekannter `type`, `restricted` ohne `permissions`, `secret` mit `permissions`, fehlerhafte Berechtigung oder CIDR, `expires_at` in der Vergangenheit oder mehr als 730 Tage in der Zukunft. |

## Beispiel

```bash
curl -X POST https://api.eu.keenauth.com/v1/api-keys \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"ci","type":"restricted","permissions":["users:read"],"expires_at":"2027-10-01T10:00:00Z"}'
```
