
# Créer une clé d'API

`POST /v1/api-keys` · autorisation `api-keys:write` · `Idempotency-Key` obligatoire

Crée une clé d'API de gestion pour l'environnement. Une clé `secret` accède à l'ensemble de l'API de gestion ; une clé `restricted` ne porte que les autorisations listées (`<resource>:<action>`).

- **Clé brute.** La réponse contient `key` une seule fois (`idp_sk_live_…`, `idp_sk_test_…`, `idp_rk_live_…` ou `idp_rk_test_…`). Elle ne peut plus être récupérée ; conservez-la immédiatement. La réponse comporte `Cache-Control: no-store`.
- **Aucune élévation.** Une clé ne peut pas créer une clé dont les autorisations dépassent les siennes, et une clé `restricted` ne peut pas créer une clé `secret`. La nouvelle clé ne peut pas expirer après la clé appelante, et une clé appelante avec `allowed_cidrs` ne peut créer que des clés limitées à des réseaux inclus dans les siens ; si `allowed_cidrs` est omis, la nouvelle clé reçoit la liste de la clé appelante (`permission_escalation`).
- **Limites.** Au plus 50 clés actives par environnement, au plus 20 blocs CIDR par clé, et une expiration au plus 730 jours à l'avance. Une clé avec `allowed_cidrs` n'est acceptée que depuis ces réseaux.
- **Rejeu idempotent.** Répéter la requête avec le même `Idempotency-Key` rejoue la réponse enregistrée sans la clé : le corps contient `secret_redacted: true` et aucune `key`. Créez une nouvelle clé si la précédente a été perdue.

## Requête

Corps :

| Champ | Type | Description |
|---|---|---|
| `name` | string | Obligatoire. De 1 à 100 caractères. |
| `type` | string | Obligatoire. `secret` ou `restricted`. |
| `permissions` | string[] | Obligatoire et non vide pour `restricted` (au plus 200) ; absent ou vide pour `secret`. Ne peut pas dépasser les autorisations de l'appelant. |
| `expires_at` | string (date-time) | Obligatoire, dans le futur, au plus 730 jours à l'avance. |
| `allowed_cidrs` | string[] | Facultatif, au plus 20 blocs CIDR. |

## Réponse

`201 Created` avec `Cache-Control: no-store`. L'objet clé comme dans la réponse de liste, plus `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>"
}
```

## Erreurs

| HTTP | `code` | Quand |
|---|---|---|
| 401 | `unauthenticated` | La clé est absente, invalide ou révoquée. |
| 403 | `insufficient_permissions` | La clé ne dispose pas de l'autorisation requise. |
| 403 | `permission_escalation` | La requête donnerait à une clé davantage d'autorisations, une plage réseau plus large ou une expiration plus tardive que la clé appelante ; une clé `restricted` tente de créer, de faire tourner ou de révoquer au-delà de ses propres autorisations, ou une autre clé tente de faire tourner ou de révoquer une clé créée depuis le tableau de bord. |
| 409 | `api_key_limit_reached` | L'environnement compte déjà le maximum de 50 clés actives. |
| 422 | `validation_failed` | Le corps est invalide : `name` manquant ou trop long, `type` inconnu, `restricted` sans `permissions`, `secret` avec `permissions`, autorisation ou CIDR mal formé, `expires_at` dans le passé ou à plus de 730 jours. |

## Exemple

```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"}'
```
