
# 계정 잠금 목록 조회

`GET /v1/attack-protection/lockouts` · 권한 `attack-protection:read`

환경의 열린 계정 잠금을 오래된 순서로 나열합니다. 무차별 대입 방어는 실패가 너무 많으면 사용자의 로그인 경로 하나(예: `password` 또는 `totp`)를 잠급니다. 사용자의 다른 경로는 계속 열려 있습니다. 만료된 잠금은 더 이상 경로를 막지 않으므로 나열되지 않습니다. 목록은 앞으로만 페이지를 넘기며 전체 개수를 반환하지 않습니다. 응답에는 IP 주소와 실패 카운터 키가 포함되지 않습니다.

## 요청

| 매개변수 | 위치 | 필수 | 설명 |
|---|---|---|---|
| `limit` | query | 아니요 | 페이지당 항목 수, 1-100(기본값 20). |
| `after` | query | 아니요 | 이전 페이지의 `list_metadata.after`에서 받은 커서. |

`before`와 `order=desc`는 지원되지 않으며 `422`를 반환합니다.

## 응답

`200 OK`.

```json
{
  "data": [
    {
      "id": "lck_01jaz8m5c3f6t9w2y4b7d0g3k6",
      "user_id": "usr_0a1b2c3d4e5f6g7h8j9k0m1n2p",
      "path": "password",
      "locked_at": "2026-10-20T09:00:00Z",
      "expires_at": "2026-10-20T09:15:00Z",
      "failure_count": 20
    }
  ],
  "list_metadata": {"before": null, "after": null}
}
```

| 필드 | 설명 |
|---|---|
| `id` | 잠금 ID, `lck_` 접두사가 붙습니다. `user.unlocked` 이벤트에도 같은 ID가 포함됩니다. |
| `user_id` | 잠긴 사용자. |
| `path` | 잠긴 로그인 경로: `password`, `totp`, `sms_2fa`, `email_2fa`, `otp` 또는 `recovery_code`. |
| `locked_at`, `expires_at` | 잠금이 시작된 시점과 자동으로 해제되는 시점. |
| `failure_count` | 잠금을 일으킨 기간 동안의 실패 시도 횟수. |

## 오류

모든 오류는 안정적인 `code`를 포함한 `application/problem+json` 본문으로 반환됩니다.

| HTTP | `code` | 언제 |
|---|---|---|
| 400 | `invalid_cursor` | 커서 형식이 잘못되었거나 다른 목록에 속합니다. |
| 422 | `validation_failed` | `limit`이 범위를 벗어났거나, `before` 또는 내림차순 `order`를 보냈습니다. |
| 401 | `unauthenticated` | API 키가 없거나, 잘못되었거나, 취소되었습니다. |
| 403 | `insufficient_permissions` | 키에 `attack-protection:read` 권한이 없습니다. |
| 429 | `rate_limited` | 요청 한도를 초과했습니다. `Retry-After`를 준수하세요. |
| 503 | `service_unavailable` | 종속 서비스를 일시적으로 사용할 수 없습니다. 나중에 다시 시도하세요. |

## 예제

```bash
curl https://api.eu.keenauth.com/v1/attack-protection/lockouts?limit=50 \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
```

CLI: `keenauth attack-protection lockouts list --limit 50`
