
# API 키 교체

`POST /v1/api-keys/{key_id}:rotate` · 권한 `api-keys:write` · 선택 사항 `Idempotency-Key`

키를 교체합니다. 같은 이름, 유형, 권한 및 `allowed_cidrs`를 가진 새 키를 생성하여 반환합니다. 기존 키는 `overlap_hours` 동안 계속 유효하며, 그 이후에는 작동하지 않습니다.

- **새 키.** 응답은 새 키를 설명합니다. `rotated_from`은 기존 키의 ID이며, `key`에는 원본 키가 한 번만 포함됩니다(`Cache-Control: no-store`). 새 키를 배포한 후 기존 키가 만료되도록 두십시오.
- **중복 기간.** 기존 키에는 미래 시점의 `revoked_at`과 `revoke_reason: rotated`가 설정됩니다. `overlap_hours: 0`이면 즉시 폐기됩니다.
- **권한 상승 불가.** 키는 자신의 권한보다 많은 권한을 가진 키를 교체할 수 없으며, `restricted` 키는 `secret` 키를 교체할 수 없습니다. 호출 키보다 나중에 만료되는 새 키는 생성할 수 없습니다. 키가 자기 자신을 교체하는 경우에도 마찬가지입니다(수명 연장은 대시보드에서 하십시오). `allowed_cidrs`가 있는 호출 키는 자신의 네트워크 범위 안에 있는 네트워크로 제한된 키만 교체할 수 있습니다. 대시보드에서 생성된 키와 그 키에서 교체된 모든 키는 자기 자신이나 대시보드에서만 교체할 수 있습니다(`permission_escalation`). 새 키는 기존 키의 `created_by`를 유지하며, 교체를 수행한 키는 감사 로그에 기록됩니다.
- **멱등 재전송.** 같은 `Idempotency-Key`로 재전송하면 `key`가 생략되고 `secret_redacted: true`가 반환됩니다.

## 요청

| 매개변수 | 위치 | 설명 |
|---|---|---|
| `key_id` | path | API 키 ID(`key_…`). |

본문:

본문은 선택 사항입니다. 본문을 생략하면 모든 기본값이 적용됩니다.

| 필드 | 유형 | 설명 |
|---|---|---|
| `overlap_hours` | integer | 선택 사항, 0–168, 기본값 24. 기존 키가 유효한 상태로 유지되는 시간(시간 단위)입니다. |
| `expires_at` | string (date-time) | 선택 사항. 새 키의 만료 시점입니다. 기본값은 현재 시각부터 365일 후이며, 호출 키의 만료 시점 이하이고 최대 730일 이내여야 합니다. |

## 응답

`200 OK`와 `Cache-Control: no-store`가 반환됩니다. 새 키 객체와 `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": "key_…",
  "revoked_at": null,
  "revoke_reason": null,
  "key": "<shown once>"
}
```

## 오류

| HTTP | `code` | 발생 조건 |
|---|---|---|
| 401 | `unauthenticated` | 키가 없거나, 잘못되었거나, 폐기되었습니다. |
| 403 | `insufficient_permissions` | 키에 필요한 권한이 없습니다. |
| 403 | `permission_escalation` | 요청이 호출 키보다 많은 권한, 더 넓은 네트워크 범위 또는 더 늦은 만료 시점을 키에 부여하려고 하거나, `restricted` 키가 자신의 권한을 넘어 생성, 교체 또는 폐기를 시도하거나, 다른 키가 대시보드에서 생성된 키를 교체 또는 폐기하려고 합니다. |
| 404 | `not_found` | 이 환경에 키가 존재하지 않습니다. |
| 409 | `conflict` | 키가 이미 폐기, 만료 또는 교체되어 활성 상태가 아닙니다. |
| 409 | `api_key_limit_reached` | 환경에 이미 활성 키가 최대 개수인 50개 있습니다. |
| 422 | `validation_failed` | 본문이 잘못되었습니다. `overlap_hours`가 0–168 범위를 벗어나거나, `expires_at`이 과거이거나 730일을 초과하여 미래에 있습니다. |

## 예시

```bash
curl -X POST "https://api.eu.keenauth.com/v1/api-keys/key_0000000000000000000000001z:rotate" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"overlap_hours":24}'
```
