
# Management-Client erstellen

`POST /v1/management-clients` · Berechtigung `management-clients:write`

Erstellt den Management-Client-Datensatz einer Anwendung vom Typ `management`: die Berechtigungen der Management-API, die der Client nutzen darf, und die Netzwerke, aus denen er aufrufen darf. Die Datensatz-ID ist die Anwendungs-ID; eine Anwendung hat daher höchstens einen Datensatz. Nur ein API-Schlüssel kann diesen Endpunkt aufrufen.

Der Client authentifiziert sich mit `private_key_jwt` (RFC 7523). Seine öffentlichen Schlüssel sind nicht Teil dieser Ressource: Registrieren Sie sie über `POST /v1/applications/{application_id}/credentials` (`type: public_key`). Das Senden von `jwks_uri` oder `public_keys` wird hier als unbekanntes Feld abgelehnt.

Der Client erhält ein Zugriffstoken vom Endpunkt `/oauth2/token` seiner Umgebung (`client_credentials`, `audience` = die Kennung der Management-API) und sendet es als `Authorization: Bearer`. Das Token ist höchstens 10 Minuten gültig. Seine Berechtigungen auf der Management-API sind die `scope`-Werte des Tokens, die auch dieser Datensatz auflistet; ein Aufruf von außerhalb von `allowed_cidrs` schlägt mit `403 ip_not_allowed` fehl. Wird der Datensatz oder die Anwendung gelöscht oder die Anwendung gesperrt, wird das Token mit `401` abgelehnt. Es werden nur JWT-Zugriffstoken akzeptiert.

## Anfrage

| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| `application_id` | String | ja | Eine Anwendung vom Typ `management` in dieser Umgebung (`app_…`). |
| `permissions` | String[] | ja | 1–200 bekannte Management-API-Berechtigungen im Format `<resource>:<action>`, zum Beispiel `users:read`. Doppelte Einträge werden entfernt und die Liste wird sortiert. |
| `allowed_cidrs` | String[] | nein | Bis zu 20 CIDR-Blöcke, zum Beispiel `203.0.113.0/24`. Host-Bits werden auf null gesetzt. Wenn Sie das Feld weglassen, wird die eigene Liste des aufrufenden Schlüssels verwendet. |

Ein eingeschränkter Schlüssel kann nur Berechtigungen vergeben, die er selbst besitzt, und ein Schlüssel mit IP-Allowlist kann nur Netzwerke innerhalb seiner eigenen vergeben; andernfalls schlägt die Anfrage mit `403 permission_escalation` fehl.

## Antwort

`201 Created`, mit einem `ETag`-Header, den Sie als `If-Match` senden, um den Datensatz zu aktualisieren oder zu löschen.

```json
{
  "application_id": "app_01h455vb4pex5vsknk084sn02q",
  "permissions": ["users:read", "users:write"],
  "allowed_cidrs": ["203.0.113.0/24"]
}
```

Jeder Schreibvorgang wird im Management-Auditprotokoll mit dem Ziel (`management_client` und der Anwendungs-ID) erfasst; Berechtigungswerte und Netzwerke werden nicht protokolliert.

## Fehler

| HTTP | code | Wann |
|---|---|---|
| 400 | `unknown_field` | Der Body enthält ein Feld, das oben nicht aufgeführt ist, etwa `jwks_uri` oder `public_keys`. |
| 403 | `insufficient_permissions` | Der Berechtigungsnachweis hat nicht `management-clients:write`, oder es ist kein API-Schlüssel. |
| 403 | `permission_escalation` | Der aufrufende Schlüssel darf diese Berechtigungen oder Netzwerke nicht vergeben. |
| 404 | `not_found` | Es gibt keine solche Anwendung in dieser Umgebung. |
| 409 | `conflict` | Die Anwendung hat bereits einen Management-Client-Datensatz. |
| 422 | `validation_failed` | Ein Feld fehlt oder ist ungültig: unbekannte Berechtigung, ungültiger CIDR, fehlerhafte `application_id` oder eine Anwendung, die nicht vom Typ `management` ist (Pointer `/application_id`). |

## Beispiel

```bash
curl -X POST https://api.eu.keenauth.com/v1/management-clients \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"application_id":"app_01h455vb4pex5vsknk084sn02q","permissions":["users:read","users:write"],"allowed_cidrs":["203.0.113.0/24"]}'
```

CLI: `keenauth management-clients create --application-id app_01h455vb4pex5vsknk084sn02q --permissions users:read,users:write --allowed-cidrs 203.0.113.0/24`
