
# 패스키 등록 시작

`POST /fapi/v1/me/passkeys/registration-options` · 환경의 로그인 호스트에서 호출

계정 포털에서 인증된 사용자에 대한 WebAuthn 등록을 시작하고, `navigator.credentials.create`에 전달할 옵션을 반환합니다. [`POST /fapi/v1/me/passkeys`](./register)로 등록을 완료하십시오. 등록은 5분 동안 유효하며, 한 번만 완료할 수 있고, 등록을 시작한 세션에서만 완료할 수 있습니다. 인증된 사용자의 `__Host-idp_session` 쿠키가 필요합니다. 쿠키가 없거나, 만료되었거나, 폐기된 경우 `401 unauthenticated`를 반환합니다. 다른 출처의 자사 애플리케이션은 대신 프런트 API 액세스 토큰(DPoP 증명을 포함한 `Authorization: DPoP <token>`)을 보낼 수 있습니다. 자세한 내용은 [프런트 API 액세스 토큰](/docs/api/fapi/front-api-token)을 참조하십시오.

패스키는 최근 10분 이내에, 보안 키는 최근 5분 이내에 세션이 검증되어 있어야 합니다. 사용자가 이미 두 번째 요소를 등록한 경우, 세션도 두 번째 요소로 열린 상태(`urn:idp:acr:mfa`)여야 합니다. 새 패스키로 이 세션의 보증 수준을 높일 수는 없습니다.

## 요청

헤더:

| 헤더 | 필수 | 설명 |
| --- | --- | --- |
| `Idp-Client` | 예 | SDK 식별자입니다. |
| `Origin` | 예 | 정확히 `https://<sign-in host>`이어야 합니다. |
| `Content-Type` | 예 | `application/json`입니다. |

본문:

| 필드 | 타입 | 필수 | 설명 |
| --- | --- | --- | --- |
| `role` | string | 예 | `passkey`: 단독으로 로그인할 수 있는 자격 증명입니다(환경에서 패스키 로그인이 켜져 있어야 합니다). `security_key`: 두 번째 요소로만 사용하는 자격 증명입니다(보안 키 두 번째 요소가 켜져 있어야 합니다). |

## 응답

`200 OK`:

```json
{
  "ceremony_id": "CQAAAAAAAAAAAAAAAAAAAA",
  "options": {"publicKey": {"challenge": "…", "rp": {"id": "example.keenauth.app", "name": "Example"}, "user": {"id": "…", "name": "ada@example.org", "displayName": "ada@example.org"}, "pubKeyCredParams": [], "timeout": 300000, "excludeCredentials": [], "authenticatorSelection": {}, "attestation": "none", "extensions": {"credProps": true}}}
}
```

`options.publicKey`를 `PublicKeyCredential.parseCreationOptionsFromJSON`에 전달하고, 그 결과를 `navigator.credentials.create`에 전달하십시오. `excludeCredentials`에는 이 Relying Party에 대한 사용자의 자격 증명이 나열되므로, 같은 인증기가 두 번 등록되지 않습니다.

## 오류

| 상태 | 코드 | 발생 조건 |
| --- | --- | --- |
| 400 | `malformed_request` | 본문이 올바른 JSON이 아닙니다. |
| 400 | `unknown_field` | 본문에 `role` 이외의 필드가 있습니다. |
| 401 | `unauthenticated` | 유효한 세션 쿠키가 없습니다. |
| 401 | `step_up_required` | 세션이 너무 오래되었거나 두 번째 요소가 필요합니다. `WWW-Authenticate` 헤더의 `max_age`(해당하는 경우 `acr_values`)로 다시 검증하십시오. |
| 403 | `origin_not_allowed` | `Origin`이 없거나 잘못되었습니다. |
| 403 | `no_allowed_method` | 환경에서 이 `role`을 허용하지 않습니다. |
| 409 | `credential_limit_reached` | 사용자가 패스키와 보안 키를 최대 개수까지 이미 등록했습니다. |
| 413 | `payload_too_large` | 본문이 너무 큽니다. |
| 415 | `unsupported_media_type` | `Content-Type`이 `application/json`이 아닙니다. |
| 422 | `validation_failed` | `role`이 없거나 `passkey` 또는 `security_key`가 아닙니다. |
| 422 | `aaguid_not_allowed` | 환경의 인증기 허용 목록이 잘못되었습니다. 수정될 때까지 등록이 차단됩니다. |

## 예시

```bash
curl -X POST https://example.keenauth.app/fapi/v1/me/passkeys/registration-options \
  -H "Idp-Client: my-app/1.0.0 (node/22.0.0)" \
  -H "Origin: https://example.keenauth.app" \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{"role": "passkey"}'
```

## 개인정보

이 엔드포인트는 개인정보(자격 증명)를 포함합니다. 저장되는 항목, 보관 기간, 삭제 방법은 [KeenAuth API의 개인정보](/docs/policies/personal-data)에서 확인하십시오. 어떤 필드에도 특수 범주의 개인정보(건강, 생체 정보, 종교, 정치적 견해, 성적 지향)를 보내지 마십시오.
