
# Create a management client

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

Creates the management client record of an application of type `management`: the management API permissions the client may use and the networks it may call from. The record ID is the application ID, so an application has at most one record. Only an API key can call this endpoint.

The client authenticates with `private_key_jwt` (RFC 7523). Its public keys are not part of this resource: register them with `POST /v1/applications/{application_id}/credentials` (`type: public_key`). Sending `jwks_uri` or `public_keys` here is rejected as an unknown field.

The client gets an access token from its environment's `/oauth2/token` endpoint (`client_credentials`, `audience` = the management API identifier) and sends it as `Authorization: Bearer`. The token is valid for at most 10 minutes. Its permissions on the management API are the token's `scope` values that this record also lists; a call from outside `allowed_cidrs` fails with `403 ip_not_allowed`. If the record or the application is deleted, or the application is suspended, the token is rejected with `401`. Only JWT access tokens are accepted.

## Request

| Field | Type | Required | Description |
|---|---|---|---|
| `application_id` | string | yes | An application of type `management` in this environment (`app_…`). |
| `permissions` | string[] | yes | 1-200 known `<resource>:<action>` management API permissions, for example `users:read`. Duplicates are removed and the list is sorted. |
| `allowed_cidrs` | string[] | no | Up to 20 CIDR blocks, for example `203.0.113.0/24`. Host bits are cleared. If you leave it out, the calling key's own list is used. |

A restricted key can only grant permissions it holds itself, and a key with an IP allowlist can only grant networks inside its own; otherwise the request fails with `403 permission_escalation`.

## Response

`201 Created`, with an `ETag` header that you send as `If-Match` to update or delete the record.

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

Every write is recorded in the management audit log with the target (`management_client` and the application ID); permission values and networks are not written to the log.

## Errors

| HTTP | code | When |
|---|---|---|
| 400 | `unknown_field` | The body contains a field that is not listed above, such as `jwks_uri` or `public_keys`. |
| 403 | `insufficient_permissions` | The credential lacks `management-clients:write`, or it is not an API key. |
| 403 | `permission_escalation` | The calling key cannot grant these permissions or networks. |
| 404 | `not_found` | There is no such application in this environment. |
| 409 | `conflict` | The application already has a management client record. |
| 422 | `validation_failed` | A field is missing or invalid: unknown permission, invalid CIDR, malformed `application_id`, or an application that is not of type `management` (pointer `/application_id`). |

## Example

```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`
