
# 연합 ID를 사용자에 연결

`POST /v1/users/{user_id}/identities` · 권한 `users:write`

연합 ID(소셜, SAML 또는 OIDC 연결의 외부 subject)를 사용자에 연결하여 사용자가 해당 연결로 로그인할 수 있게 합니다. `linked_via` 값은 항상 `admin_api`입니다. 연결은 이 환경에서 활성화된 연결이어야 하며, 종류가 `type`과 일치해야 합니다. 동일한 ID가 이 사용자 또는 다른 사용자에 이미 연결되어 있으면 요청이 `409`로 실패하며, 소유자는 공개되지 않습니다. 외부 subject는 개인 데이터이므로 암호화되어 저장되고 반환되지 않으며, 관리 감사 기록 `user.identity_linked`(행위자: API 키)에도 포함되지 않습니다. 두 사용자를 병합하는 기능(`source_user_id`)은 제공되지 않으며, 알 수 없는 필드는 `400 unknown_field`를 반환합니다.

## 요청

| 매개변수 | 위치 | 필수 | 설명 |
|---|---|---|---|
| `user_id` | path | 예 | 사용자 ID, 접두사 `usr_`. |

| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| `type` | string | 예 | `social`, `saml` 또는 `oidc`. 연결과 일치해야 합니다(소셜 연결은 `social`, 같은 전략의 엔터프라이즈 연결은 `saml`/`oidc`). |
| `connection_id` | string | 예 | 연결 ID, 접두사 `conn_`. |
| `subject` | string | 예 | ID 공급자의 외부 subject(OIDC `sub`, SAML NameID), UTF-8 기준 최대 1024바이트. |

## 응답

`201 Created`와 함께 새 ID 정보를 반환하며, 형식은 `GET /v1/users/{user_id}/identities`가 반환하는 형식과 같습니다.

```json
{
  "id": "idn_0a1b2c3d4e5f6g7h8j9k0m1n2r",
  "type": "oidc",
  "connection_id": "conn_0a1b2c3d4e5f6g7h8j9k0m1n2s",
  "provider": null,
  "linked_via": "admin_api",
  "created_at": "2026-01-15T09:30:00Z"
}
```

## 오류

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

| HTTP | `code` | 발생 조건 |
|---|---|---|
| 400 | `malformed_request`, `unknown_field` | 본문이 올바른 JSON이 아니거나 알 수 없는 필드가 있습니다. |
| 409 | `conflict` | ID가 이미 사용자에 연결되어 있거나(`errors[]`: `identity_already_linked`), 사용자가 사용자당 ID 한도에 도달했습니다(`errors[]`: `identity_limit_reached`). |
| 415 | `unsupported_media_type` | 본문이 `Content-Type: application/json` 없이 전송되었습니다. |
| 422 | `validation_failed` | 필드가 없거나 올바르지 않습니다(`/type`, `/connection_id`, `/subject`). 또는 연결이 이 환경에서 활성화되지 않았거나 `type`과 일치하지 않습니다(`errors[]`: `/connection_id`, `connection_unavailable`). |
| 404 | `not_found` | 이 환경에 사용자가 없거나, 삭제 중이거나, ID 형식이 잘못되었습니다. |
| 401 | `unauthenticated` | API 키가 없거나, 올바르지 않거나, 취소되었습니다. |
| 403 | `insufficient_permissions` | 키에 `users:write` 권한이 없습니다. |
| 429 | `rate_limited` | 요청 한도를 초과했습니다. `Retry-After`를 따르십시오. |
| 503 | `service_unavailable` | 종속 서비스를 일시적으로 사용할 수 없습니다. 나중에 다시 시도하십시오. |

## 예제

```bash
curl -X POST https://api.eu.keenauth.com/v1/users/usr_0a1b2c3d4e5f6g7h8j9k0m1n2p/identities \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "oidc", "connection_id": "conn_0a1b2c3d4e5f6g7h8j9k0m1n2s", "subject": "248289761001"}'
```

## 개인 데이터

이 엔드포인트는 개인 데이터인 연결된 ID를 다룹니다. [KeenAuth API의 개인 데이터](/docs/policies/personal-data)에서 저장되는 항목, 보관 기간 및 삭제 방법을 설명합니다. 어떤 필드에도 특수 범주의 개인 데이터(건강, 생体 정보, 종교, 정치적 견해, 성적 지향)를 보내지 마십시오.
