---
url: 'https://www.corbado.com/ko/blog/webauthn-relying-party-id-rpid-passkeys'
title: 'WebAuthn 의존 당사자 ID(rpID) 및 패스키: 도메인 및 네이티브 앱'
description: '이 블로그 게시물은 패스키 인증을 위한 WebAuthn 의존 당사자 ID(Relying Party ID)에 대해 설명합니다. 올바른 구성, 도메인 일치 및 네이티브 앱 구성 방법을 다룹니다.'
lang: 'ko'
author: 'Vincent Delitz'
date: '2026-06-15T13:56:18.745Z'
lastModified: '2026-06-16T06:09:29.212Z'
keywords: '의존 당사자 ID, 패스키 인증, WebAuthn, 네이티브 앱 구성, 도메인 일치'
category: 'WebAuthn Know-How'
---

# WebAuthn 의존 당사자 ID(rpID) 및 패스키: 도메인 및 네이티브 앱

## Key Facts

- \*\*의존 당사자 ID(Relying Party ID)\*\*는 모든 패스키에 내장된 도메인입니다. 브라우저
  출처가 일치하지 않으면 인증이 실패하므로 패스키는 피싱에 대해 강력한 저항력을 갖습니다.
- **RP ID**는 \*\*공개 접미사 목록(Public Suffix List)\*\*에 있어서는 안 되며, 이를
  변경하면 기존의 모든 패스키가 무효화됩니다. 미래를 대비해 기본적으로 루트 도메인을
  사용하세요.
- iOS 앱은 RP ID 아래의 `/.well-known/` 경로에 **apple-app-site-association** 파일이
  필요합니다. Android는 동일한 경로에 **assetlinks.json**이 필요합니다. 새 파일이 캐시되는
  데 최대 24시간이 걸릴 수 있습니다.
- 여러 루트 도메인에서 패스키를 공유하려면 `.well-known/webauthn`을 통한 \*\*관련 출처
  요청(Related Origin Requests)\*\*이 필요합니다. 웹 및 네이티브 등 모든 앱에 대해 하나의
  RP ID가 있는 단일 WebAuthn 서버를 사용하세요.

## 1. 소개

[TikTok](https://www.corbado.com/blog/tiktok-passkeys), GitHub, [WhatsApp](https://www.corbado.com/blog/whatsapp-passkeys), X(Twitter),
[LinkedIn](https://www.corbado.com/blog/linkedin-passkeys), Amazon과 같은 거대 기술 기업들이 패스키를 도입하거나
이미 도입함에 따라 패스키 인증은 빠르게 표준으로 자리 잡고 있습니다. 기술 업계가 간단하고
안전한 인증의 중요성을 인식하고 있음이 분명해졌습니다.

[Face ID](https://www.corbado.com/faq/is-face-id-passkey), Touch ID 또는
[Windows Hello](https://www.corbado.com/glossary/windows-hello)로 인증하는 원활한 사용자 경험을 넘어, 패스키는
비밀번호와 같은 기존 인증 방식과 비교할 수 없는 탁월한 보안을 제공합니다. 가장 눈에 띄는
기능 중 하나는 강력한 피싱 저항성입니다.

피싱 공격은 피해자를 속여 원래 사이트로 위장한 가짜 사이트에 자격 증명을 제공하도록 하는
공격입니다. 예를 들어, 은행에서 보낸 것처럼 보이는 로그인 요청 이메일을 받았다고 가정해
보겠습니다. 링크를 클릭하면 웹사이트가 합법적인 것처럼 보이므로 자격 증명을 입력하게 되고,
공격자는 이를 사용하여 원래 사이트에 로그인할 수 있습니다. 이는 디지털 시대에 점점 더 큰
문제가 되고 있으며,
[Okta ](https://www.darkreading.com/application-security/okta-flaw-involved-mgm-resorts-breach-attackers-claim)(인증
제공업체입니다!)나 [Retool ](https://retool.com/blog/mfa-isnt-mfa/)과 같은 주요 기업조차도
스피어 피싱 공격(개별 피해자를 개인화된 피싱 기법으로 특별히 표적으로 삼는 피싱의 특수한
형태)의 피해자가 되어 강력한 보안 조치의 필요성을 강조하고 있습니다.

반면, 패스키를 사용하는 경우 사이트가 가짜라면 인증에 실패하게 됩니다. 이는 패스키가
\*\*의존 당사자 ID(Relying Party ID)\*\*를 통해 생성된 도메인에 바인딩되어 있기
때문입니다.

> 다른 사이트에서는 패스키로 로그인할 수 없으므로 패스키는 피싱에 강력하게 저항합니다(물론
> 어떤 시스템도 모든 공격 벡터에 완벽히 면역될 수는 없습니다).

이 메커니즘은 비밀번호 없는 인증을 위한 패스키의 기본 웹 표준인 WebAuthn에 내장되어
있습니다. WebAuthn은 등록과 인증이라는 두 가지 핵심 세리머니를 기반으로 합니다.

등록(가입) 세리머니 동안 웹 또는 네이티브 앱을 통해 온라인 서비스(의존 당사자,
[Relying Party](https://www.corbado.com/glossary/relying-party))를 위한 새 패스키가 생성됩니다. 이 과정에서
패스키가 생성되는 도메인(의존 당사자 ID)이 패스키에 저장됩니다.

이를 통해 인증(로그인) 세리머니는 웹 또는 네이티브 앱이 속한 온라인 서비스(의존 당사자)가
패스키에 저장된 의존 당사자 ID와 일치하는지 확인할 수 있습니다.

다음에서는 이 [도메인 일치](#what-relying-party-id) 프로세스가 어떻게 작동하며 특히
네이티브 앱이 어떻게 보호되는지 자세히 살펴보겠습니다.

## 2. 의존 당사자 ID란 무엇인가요?

[**의존 당사자 ID(Relying Party ID)**](https://www.w3.org/TR/webauthn-2/#relying-party-identifier)는
본질적으로 패스키 내에 저장된 도메인으로, 현재 브라우저 URL(모든 요청에서 자동으로
전송되는 사용자의 출처)이 일치하는 경우에만 패스키가 작동하도록
보장합니다([아래](#integration-options-native-apps)의 네이티브 앱 접근 방식 참조). 이는
WebAuthn 사양의 중요한 구성 요소이며, [여기](https://www.w3.org/TR/webauthn-2/)에서 자세히
알아볼 수 있습니다. 의존 당사자 ID는 루트 도메인(예: `corbado.com`)이거나 하위
도메인(`auth.corbado.com`)일 수 있습니다. 공개 접미사 목록에 있는 경우 해당 루트 도메인을
의존 당사자 ID로 저장할 수 없습니다(목록 및 공개 접미사 감지 라이브러리는
[여기](https://publicsuffix.org/learn/)에서 찾을 수 있습니다). 온라인 서비스에 대한 의존
당사자 ID를 변경하면 기존 패스키가 작동하지 않게 됩니다(예외: 새 의존 당사자 ID가 기존
의존 당사자 ID의 하위 도메인이거나, 관련 도메인 간 패스키 재사용을 허용하도록
`.well-known/webauthn`을 통해 관련 출처 요청이 구성된 경우).

인증 과정에서 의존 당사자 ID는 브라우저 URL(사용자의 출처)과 일치하는지 확인됩니다. 여기서
일치한다는 것은 다음 중 하나를 의미합니다:

- 브라우저 URL(사용자 출처)이 의존 당사자 ID와 정확히 일치하거나
- 브라우저 URL(사용자 출처)이 의존 당사자 ID와 일치하는 하위 도메인이며 상위 도메인을
  등록할 수 있습니다(예: `com` 또는 공개 접미사 목록의 모든 도메인은 작동하지 않음).

다음은 어떤 _originalHost_(두 번째 열)가 상위 도메인에 접근할 수 있는지 보여주는 자세한
개요입니다:

![relying party id table](https://www.corbado.com/website-assets/relying_party_id_table_4c98cc04f4.jpg)

다음은 파싱된
[**PublicKeyCredentialCreationOptions**](https://www.w3.org/TR/webauthn-2/#iface-pkcredential)를
보여줍니다:

```json
{
    "publicKey": {
        "attestation": "direct",
        "authenticatorSelection": {
            "authenticatorAttachment": "platform",
            "requireResidentKey": false,
            "userVerification": "preferred"
        },
        "challenge": "qNqrdXUrk5S7dCM1MAYH3qSVDXznb-6prQoGqiACR10=",
        "excludeCredentials": [],
        "pubKeyCredParams": [
            {
                "alg": -7,
                "type": "public-key"
            }
        ],
        "rp": {
            "id": "corbado.com",
            "name": "Corbado"
        },
        "timeout": 30000,
        "user": {
            "displayName": "Corbado user",
            "id": "bz9ZDfHzOBLycqISTAdWwWIZt8VO-6mT3hBNXS5jwmY="
        }
    }
}
```

`rp`는 의존 당사자(Relying Party)를 의미합니다.

의존 당사자 ID의 주요 이점 중 하나는 피싱 공격을 예방한다는 것입니다. 다음 시나리오를
상상해 보세요:

1. 공격자가 당신의 이름으로 로그인하여 공격자의 계정으로 송금하기 위해 당신의
   [PayPal](https://www.corbado.com/blog/paypal-passkeys) 자격 증명을 훔치려는 가짜 웹사이트인
   [PayPal](https://www.corbado.com/blog/paypal-passkeys) 복제본을 개발합니다. 이 가짜
   [PayPal](https://www.corbado.com/blog/paypal-passkeys) 웹사이트는 paybal.com 도메인에 호스팅되어 있으므로
   첫눈에 다른 도메인인지 알기 어려운 경우가 많습니다.
2. 당신은 과거에 합법적인 PayPal 사이트에 대한 패스키를 이미 생성했습니다. 이 패스키에는
   의존 당사자 ID paypal.com이 저장되어 있습니다.
3. 당신이 paybal.com의 가짜 PayPal 웹사이트를 방문하고(이 사이트를 방문할 때 요청 출처는
   paybal.com입니다\*) 사이트는 당신의 기기(인증자)에 의존 당사자 ID `paypal.com`에 대한
   챌린지를 전송하고(여기서 사용자를 속이려 시도함) 의존 당사자 ID paypal.com에 대해
   패스키로 서명하도록 요청합니다.
4. 당신의 기기(인증자)는 요청의 출처(`paybal.com`)와 패스키에 저장된 의존 당사자
   ID(`paypal.com`)가 일치하는지 확인합니다.
5. 이 둘은 명백히 일치하지 않으므로 인증이 실패하고, 이로 인해 공격자가 당신의 PayPal
   계정에 접근하는 것을 막을 수 있습니다.

다음 다이어그램은 이 피싱 예방 메커니즘을 설명합니다.

_네이티브 앱의 경우, 플랫폼에 따라 출처 처리 방식이 다릅니다: Android에서는 출처가
`android:apk-key-hash:<SHA256_fingerprint>` 형식으로 지정됩니다. iOS에서 WebAuthn 출처는
RP 웹 출처(예: `https://paypal.com`)입니다. 두 경우 모두 네이티브 앱과 서버 간의 신뢰는
해당 연결 파일(아래 [참조](#configuring-relying-party-native-apps))을 통해 확인됩니다.
네이티브 앱에 대한 출처 확인이 작동하는 방식에 대한 자세한 내용은 네이티브 앱을 위한
WebAuthn 출처 확인에 대한 전용 가이드를 참조하세요._

## 3. 네이티브 앱을 위한 두 가지 다른 통합 옵션

네이티브 앱에 패스키를 구현하기 위해 개발자는 [WebView](https://www.corbado.com/blog/native-app-passkeys)를 통해
추가하거나 네이티브 방식으로 통합하는 것 중 하나를 결정할 수 있습니다. 다음에서 두 접근
방식의 장단점을 살펴보겠습니다.

### 3.1 WebView를 통한 패스키 통합

![Passkey Integration WebView (GitHub)](https://www.corbado.com/website-assets/650c601b1eb462e25702a870_android_webview_passkey_github_8bc81d9852.jpg)

패스키 통합에 **WebView**\*를 사용한다는 것은 인증 프로세스를 처리하기 위해 네이티브 앱
내에 웹 브라우저를 포함시키는 것을 의미합니다. 이 접근 방식은 본질적으로 앱 내부에 웹
페이지를 표시하므로 네이티브 플랫폼에 맞춰 코드를 다시 작성할 필요 없이 웹 기반 인증
흐름을 더 쉽게 재사용할 수 있게 해줍니다. 그러나 몇 가지 단점이 있습니다.
[WebView](https://www.corbado.com/blog/native-app-passkeys)는 모든 패스키 기능을 지원하지 않을 수 있으며,
안전하게 구현되지 않을 경우 "중간자(man-in-the-middle)" 공격의 위험이 있습니다. 또한
사용자 경험이 네이티브 통합만큼 매끄럽지 않을 수 있고 여러 기기 및 OS 버전에서 일관된
동작을 유지하는 데 어려움이 있을 수 있습니다.

_\*여러 종류의 WebView가 있습니다: iOS에서는 WKWebView, SFSafariViewController 또는
OAuth/OpenID Connect 기반 인증 흐름을 위한 SFAuthenticationSession /
ASWebAuthenticationSession이 있고, Android에서는 WebView, CCT(Chrome Custom Tabs)가
있습니다. 자세한 내용은 이 블로그 게시물을 참조하세요. 네이티브 통합을 원하지 않는 경우
패스키의 컨텍스트에서 SFSafariViewController/ ASWebAuthenticationSession 및 Chrome Custom
Tabs를 사용하는 것이 좋습니다._

### 3.2 네이티브 패스키 통합

![Native Passkey Integration (Kayak)](https://www.corbado.com/website-assets/650c625cac723f594137a029_android_native_passkey_kayak_0f689e761e.jpg)

**네이티브 통합**은 플랫폼별 API 및 라이브러리를 사용하여
[iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios) 또는
[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) 앱에 패스키 기능을 직접 구축하는 것을
포함합니다. 이 방법은 네이티브 앱과 [WebView](https://www.corbado.com/blog/native-app-passkeys) 간에 전환할
필요가 없기 때문에 더 매끄러운 사용자 경험을 제공합니다. 또한 더 나은 성능과 더 일관된 룩
앤 필을 허용합니다. 보안 관점에서 네이티브 통합은 특히 플랫폼별 보안 기능과 결합될 때 특정
유형의 공격에 대해 강화된 보호를 제공할 수 있습니다. 그러나 개발자가 각 플랫폼(Android 및
[iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios))에 대해 별도의 코드를 작성하고 유지 관리해야
하므로 구현 노력이 더 클 수 있습니다. 또한 최신 패스키 / WebAuthn 사양을 최신 상태로
유지하려면 더 잦은 앱 업데이트가 필요할 수 있습니다.

다음에서는 네이티브 패스키 통합에 초점을 맞추겠습니다.

## 4. 네이티브 앱을 위한 의존 당사자 구성

네이티브 앱(예: iOS 또는 [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) 앱)은 웹 앱에
비해 해결해야 할 과제가 있습니다. 웹 앱과 달리 의존 당사자 ID와 일치시킬 브라우저 URL이
없습니다. 그럼에도 불구하고 동일한 수준의 보안을 보장하기 위해 도메인은 \*\*연결
파일(association files)\*\*을 통해 네이티브 앱에 연결되어 도메인과 네이티브 앱 간에 신뢰가
설정됩니다.

이는 패스키가 웹 앱에서 생성되었고 네이티브 앱에서 동일한 의존 당사자 ID로 사용되어야 하는
경우(또는 그 반대의 경우) 특히 중요합니다.

### 4.1 iOS의 연결 파일: apple-app-site-association

iOS는 apple-app-site-association 파일을 사용합니다. 이 파일에는 다양한
권한(entitlements)이 포함되어 있지만, WebAuthn 및 패스키의 경우 webcredentials 권한이
중요합니다.

```json
{
    "webcredentials": {
        "apps": ["9RF9KY88B2.com.corbado.passkeys"]
    }
}
```

webcredentials.apps에 애플리케이션 식별자 접두사(Application Identifier Prefix, 예:
`9RF9KY77B2`) 및 번들 식별자(Bundle Identifier, 예: `com.corbado.passkeys`)를 저장해야
합니다.

iOS 네이티브 앱이 작동하려면 apple-app-site-association 파일이 의존 당사자 ID의
`/.well-known`
디렉토리(`https://<의존 당사자 ID>/.well-known/apple-app-site-association`)에 저장되어야
합니다.

라이브 예제는
[여기](https://pro-6244024196016258271.frontendapi.cloud.corbado.io/.well-known/apple-app-site-association)를
참조하세요.

### 4.2 Android의 연결 파일: assetlinks.json

[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android)는 `assetlinks.json` 파일을 사용하며, iOS의
경우와 마찬가지로 WebAuthn 및 패스키에 대한 특정 구성이 필요합니다.

```json
[
    {
        "relation": [
            "delegate_permission/common.handle_all_urls",
            "delegate_permission/common.get_login_creds"
        ],
        "target": {
            "namespace": "android_app",
            "package_name": "com.corbado.passkeys.pub",
            "sha256_cert_fingerprints": [
                "F8:90:4E:9A:99:01:71:75:25:38:D5:36:16:2D:B3:65:EB:41:51:D4:53:9A:72:BC:4B:56:C5:16:43:62:E2:C0"
            ]
        }
    }
]
```

relation 값인 `delegate_permission/common.handle_all_urls` 및
`delegate_permission/common.get_login_creds`를 설정해야 합니다. 또한 패키지 이름과 서명
인증서의 SHA-256 지문을 추가해야 합니다.

네이티브 앱과 웹 앱 간에 패스키 공유를 허용하려면 두 개의 항목을 추가해야 합니다. 하나는
네임스페이스 web에 대한 것이고 다른 하나는 네임스페이스 android_app에 대한 것입니다.

라이브 예제는
[여기](https://pro-6244024196016258271.frontendapi.cloud.corbado.io/.well-known/assetlinks.json)를
참조하세요.

Android 앱이 작동하려면 assetlinks.json 파일이 의존 당사자 ID의 `/.well-known` 디렉토리
`https://<의존 당사자 ID>/.well-known/assetlinks.json`에 저장되어야 합니다. 이는 iOS의
경우와 거의 유사합니다.

네이티브 Android / iOS 앱과 웹 앱 간에 패스키를 공유하는 샘플 구현을 확인하려면 이 블로그
게시물을 참조하세요.

## 5. 네이티브 앱과 웹 앱 간의 신뢰 구축

### 5.1 iOS

iOS 앱과 웹 앱 간에 신뢰를 구축하는 프로세스는 다음과 같습니다:

1. iOS 앱 개발자는 네이티브 앱과 연결할 도메인 목록을 지정해야 합니다. 이러한 도메인은 iOS
   앱의 권한(entitlements)에 하드코딩됩니다. 예:

- webcredentials:auth.Corbado.com
- webcredentials:\*.Corbado.com

2. iOS 앱이 설치되거나 업데이트될 때마다 iOS는 iOS 앱 권한 목록의 각 항목에 대해
   apple-app-site-association 파일을 다운로드합니다.

3. iOS 앱 내에서 자격 증명(예: 패스키)이 생성될 때, iOS 앱은 다음 두 가지 측면을 확인하여
   의존 당사자 서버 도메인이 iOS 앱과 연결되어 있는지 유효성을 검사합니다:

- 기기에 이 의존 당사자 서버 도메인에 대한 `apple-app-site-association` 파일이 존재하는가?
- 해당 iOS 앱이 그 `apple-app-site-association` 파일에 나열되어 있는가?

두 질문 모두에 "예"라고 답할 수 있는 경우에만 iOS 앱 내에서 패스키를 생성할 수 있습니다.

### 5.2 Android

Android 앱과 웹 앱 간에 신뢰를 구축하는 프로세스는 다음과 같습니다:

1. Android 앱 개발자는 Android 앱과 연결할 도메인 목록을 지정해야 합니다. 이러한 도메인은
   assetlinks.json 파일의 네임스페이스가 web인 target으로 저장됩니다. Android 앱과 웹 앱이
   자격 증명을 공유함을 선언하려면 `delegate_permission/common.get_login_creds`를 지정해야
   합니다. 자세한 내용은
   [여기](https://developer.android.com/training/sign-in/passkeys#add-support-dal)에서
   확인할 수 있습니다.

2. Android 앱 내에서 패스키가 생성되면 Android 앱은 `assetlinks.json`을 확인하여 의존
   당사자 ID가 Android 앱과 연결되어 있는지 유효성을 검사합니다:

- `https://<의존 당사자 ID>./well-known/assetlinks.json`에 이 의존 당사자 ID에 대한
  `assetlinks.json` 파일이 존재하는가?
- Android 앱이 타겟으로 올바르게 정의되어 있는가.

3. 두 질문 모두에 "예"라고 답할 수 있는 경우에만 Android 앱 내에서 패스키를 생성할 수
   있습니다.

아래 다이어그램은 이러한 신뢰 구축 프로세스를 나란히 비교합니다.

## 6. Android, iOS 및 Flutter 설정 개요

다음에서는 네이티브 앱에 패스키 인증을 올바르게 설정하는 데 필요한 다양한 설정에 대한
자세한 개요를 제공합니다.

| 기능                                         | iOS                                                                                                                                                   | Android                                                                                                                                                                                                                                                                                                                                                                            |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 네이티브 패스키 인증을 위한 공식 구현 가이드 | Apple Developer                                                                                                                                       | Google Developer                                                                                                                                                                                                                                                                                                                                                                   |
| 웹 앱과 패스키 공유 허용                     | 예, apple-app-site-association 파일을 통해                                                                                                            | 예, assetlinks.json을 통해                                                                                                                                                                                                                                                                                                                                                         |
| 연결 파일 위치                               | [https://acme.com/.well-known/apple-app-site-association](https://acme.com/.well-known/apple-app-site-association)                                    | [https://acme.com/.well-known/assetlinks.json](https://acme.com/.well-known/assetlinks.json)                                                                                                                                                                                                                                                                                       |
| 파일 캐시 여부                               | 예(iOS 14부터), 초기 동기화에 최대 24시간 소요 가능                                                                                                   | 예(Play Services에서)                                                                                                                                                                                                                                                                                                                                                              |
| 우회 가능 여부                               | 예, alternate mode 섹션 사용                                                                                                                          | 아니오                                                                                                                                                                                                                                                                                                                                                                             |
| 테스트 도구                                  | apple-app-site-association 테스트                                                                                                                     | assetlinks.json 테스트                                                                                                                                                                                                                                                                                                                                                             |
| 샘플이 포함된 앱 식별자                      | `<Application Identifier Prefix>.<Bundle Identifier>`, 예: `T84QZS65DQ.com.facebook.Messenger`                                                        | SHA256 지문, 예: `E3:F9:E1:E0:CF:99:D0:E5:6A:05:5B:A6: 5E:24:1B:33:99: 7F:CE:A5:24:32: 6B:0C:DD:6E:C1:32: 7E:D0:FD:C1`                                                                                                                                                                                                                                                             |
| 앱 식별자 위치                               | Team Application Identifier Prefix는 developer.apple.com의 개발자 계정에서 찾을 수 있으며 Bundle Identifier는 XCode 프로젝트 내부의 정확한 이름입니다 | 이미 업로드된 경우: Google Play Console &gt; 릴리스 관리(Release management) &gt; 앱 서명(App signing). 로컬: `keytool -list -v -keystore <keystore path> -alias <key alias> -storepass <store password> -keypass <key password>`                                                                                                                                                  |
| 앱을 웹에 연결하는 섹션 이름                 | applinks(패스키에는 필요하지 않음)                                                                                                                    | `delegate_permission/common.handle_all_urls`(패스키에 필요함)                                                                                                                                                                                                                                                                                                                      |
| 앱/웹 간 자격 증명 공유를 허용하는 섹션 이름 | webcredentials                                                                                                                                        | `delegate_permission/common.get_login_creds`                                                                                                                                                                                                                                                                                                                                       |
| 모든 연결 파일의 레지스트리                  | XCode 개발 환경에서 활성화하고 연결된 도메인 추가(권한 파일을 생성하기 위한 속성 설정)                                                                | Credential Manager API를 사용하는 경우 패스키에 매니페스트의 assetlinks.json 레지스트리가 필요하지 않습니다(그러나 비밀번호에는 필요함). Credential Manager API를 사용하지 않는 경우, 특정 활동(Android 앱 소스 코드의 일부)의 AndroidManifest.xml에 있는 `<data>` 항목에 호스트 이름을 나열해야 합니다. `<intent-filter android:autoVerify="true">`는 autoVerify=true여야 합니다. |

[Flutter](https://www.corbado.com/blog/flutter-passkeys-package)의 경우 Android 또는 iOS의 해당 규칙이
적용됩니다. 유일한 [Flutter](https://www.corbado.com/blog/flutter-passkeys-package) 관련 설정은 연결 파일의
레지스트리이며, 여기에 다음을 추가해야 합니다:

- Android의 경우:
  [flutter_deeplinking_enabled를 AndroidManifest.xml에 추가](https://docs.flutter.dev/cookbook/navigation/set-up-app-links)
- iOS의 경우:
  [FlutterDeepLinkingEnabled true를 Info.plist에 추가](https://docs.flutter.dev/cookbook/navigation/set-up-universal-links)

## 7. 유효 및 무효 의존 당사자 ID 및 연결 파일 예시

우리가 직접 경험했듯이 다양한 수준의 (하위) 도메인 및 CNAME을 사용하여 의존 당사자 ID를
작업하는 것은 꽤 어려운 작업일 수 있으므로 네 가지 별개의 예시를 제시하고 작동하는 이유와
방법에 대해 설명합니다.

CNAME 테이블 행은 패스키 인증에 필요하지 않으며 단지 추가하고자 했던 연구 결과일 뿐이라는
점에 유의하세요.

### 7.1 예시 1: 의존 당사자가 루트 도메인인 경우

| **의존 당사자 ID**                       | corbado.com                                                                                                              |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **권한 (iOS 전용)**                      | webcredentials:corbado.com                                                                                               |
| **apple-app-site-association 파일 위치** | [https://corbado.com/.well-known/apple-app-site-association](https://corbado.com/.well-known/apple-app-site-association) |
| **assetlinks.json 파일 위치**            | [https://corbado.com/.well-known/assetlinks.json](https://corbado.com/.well-known/assetlinks.json)                       |
| **CNAME**                                | 해당 없음                                                                                                                |

이 예시에서는 Corbado.com의 `apple-app-site-association` / `assetlinks.json` 파일이 의존
당사자 ID와 동일한 위치에 있기 때문에 네이티브 앱이 설치 / 업데이트될 때 아무 문제 없이
다운로드될 수 있습니다.

**의존 당사자 ID에 대한 패스키를 생성할 수 있습니다.**

### 7.2 예시 2: 의존 당사자가 하위 도메인이고 CNAME이 설정된 경우

| 의존 당사자 ID                           | auth.corbado.com                                                                                                                         |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **권한 (iOS 전용)**                      | webcredentials:auth.corbado.com                                                                                                          |
| **apple-app-site-association 파일 위치** | [https://pro-123.passkeys.eu/.well-known/apple-app-site-association](https://pro-123.passkeys.eu/.well-known/apple-app-site-association) |
| **assetlinks.json 파일 위치**            | [https://pro-123.passkeys.eu/.well-known/assetlinks.json](https://pro-123.passkeys.eu/.well-known/assetlinks.json)                       |
| **CNAME**                                | auth.corbado.com =&gt; pro-123.passkeys.eu                                                                                               |

이 예시에서는 CNAME이 의존 당사자 ID에서 저장된 위치를 가리키고 파일이 의존 당사자 ID와
동일한 위치에 있기 때문에 auth.corbado.com의 `apple-app-site-association` /
`assetlinks.json` 파일이 네이티브 앱이 설치 / 업데이트될 때 아무 문제 없이 다운로드될 수
있습니다.

**의존 당사자 ID에 대한 패스키를 생성할 수 있습니다.**

### 7.3 예시 3: 의존 당사자가 루트 도메인이고 CNAME이 설정된 경우

| 의존 당사자 ID                           | corbado.com                                                                                                                              |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **권한 (iOS 전용)**                      | webcredentials:corbado.com; webcredentials:auth.corbado.com                                                                              |
| **apple-app-site-association 파일 위치** | [https://pro-123.passkeys.eu/.well-known/apple-app-site-association](https://pro-123.passkeys.eu/.well-known/apple-app-site-association) |
| **assetlinks.json 파일 위치**            | [https://pro-123.passkeys.eu/.well-known/assetlinks.json](https://pro-123.passkeys.eu/.well-known/assetlinks.json)                       |
| **CNAME**                                | auth.corbado.com =&gt; pro-123.passkeys.eu                                                                                               |

이 예시에서는 CNAME으로 인해 파일이 `auth.corbado.com`에서 예상하는 위치에 있기 때문에
auth.corbado.com의 `apple-app-site-association` / `assetlinks.json` 파일이 네이티브 앱이
설치 / 업데이트될 때 아무 문제 없이 다운로드될 수 있습니다.

하지만: corbado.com의 `apple-site-association-file` / `assetlinks.json`은 파일이 예상되는
`https://corbado.com/.well-known/apple-app-site-association` /
`https://corbado.com/.well-known/assetlinks.json` 위치에 존재하지 않고 CNAME이 가리키지
않기 때문에 네이티브 앱이 설치 / 업데이트될 때 다운로드할 수 없습니다.

**의존 당사자 ID에 대한 패스키를 생성할 수 없습니다.**

### 7.4 예시 4: 의존 당사자가 하위 도메인이고 와일드카드 권한이 설정된 경우

| 의존 당사자 ID                           | auth.corbado.com                                                                                                         |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **권한 (iOS 전용)**                      | webcredentials:\*.corbado.com                                                                                            |
| **apple-app-site-association 파일 위치** | [https://corbado.com/.well-known/apple-app-site-association](https://corbado.com/.well-known/apple-app-site-association) |
| **assetlinks.json 파일 위치**            | [https://corbado.com/.well-known/assetlinks.json](https://corbado.com/.well-known/assetlinks.json)                       |
| **CNAME**                                | 해당 없음                                                                                                                |

이 예시에서는 파일이 예상되는 위치에 있고 webcredentials 권한(`*.corbado.com`)이 의존
당사자 ID(`auth.corbado.com`)와 일치하기 때문에 corbado.com의 `apple-app-site-association`
파일이 네이티브 앱이 설치 / 업데이트될 때 아무 문제 없이 다운로드될 수 있습니다. Android는
(와일드카드) 권한과 같은 기능이 작동하지 않으므로 이 예시는 Android에서는 작동하지
않습니다. 일반적으로 이러한 방식의 의존 당사자 ID 정의는 권장하지 않습니다.

**의존 당사자 ID에 대한 패스키를 생성할 수 있습니다.**

## 8. 일반적인 의존 당사자 ID 실수 및 방지 방법

### 8.1 하위 도메인에서 루트 도메인으로 의존 당사자 ID 변경

**실수:**

개발을 시작하고 의존 당사자 ID로 하위 도메인(예: `login.acme.com`)을 정의했습니다. 첫 번째
사용자들이 이 의존 당사자 ID에 대한 패스키를 생성했습니다. 그런 다음 다른 하위 도메인(예:
`app.acme.com`)에서의 인증을 위해서도 이 패스키들이 필요하다는 것을 알게 되었습니다.
사용자의 출처와 새 하위 도메인의 의존 당사자 ID가 일치하지 않으므로 사용자는 패스키로
로그인할 수 없습니다. WebAuthn 설정에서 의존 당사자 ID를 `acme.com`으로 변경하면 새 출처와
기존 패스키에 저장된 의존 당사자 ID가 일치하지 않으므로 모든 기존 패스키가 무효화됩니다.

**해결 방법:**

의존 당사자 ID를 정의할 때 이는 다소 확정적인 사항이므로 초기에 두 번 확인하세요. 잘
모르겠고 미래에 다른 하위 도메인에서 인증을 위해 패스키가 필요할 가능성에 대비하고 싶다면,
[공개 접미사 목록](https://publicsuffix.org/learn/)에 있는 경우가 아니라면 루트 도메인(예:
acme.com)을 의존 당사자 ID로 사용할 것을 권장합니다.

### 8.2 네이티브 앱과 웹 앱의 의존 당사자 ID 불일치

**실수:**

네이티브 앱과 웹 앱을 동시에 개발하고 있습니다. 속도를 높이기 위해 (네이티브 앱과 웹 앱에
대해 서로 다른 의존 당사자 ID를 사용하는) 두 개의 서로 다른 WebAuthn 서버를 사용합니다.
사용자가 첫 번째 패스키를 생성함에 따라 해당 의존 당사자 ID가 패스키에 저장됩니다. 웹
앱에서 생성된 패스키로 네이티브 앱에서 로그인을 시도하는 것과 같이 동일한 패스키로 교차
기기/플랫폼 간 로그인을 허용하는 것은 더 이상 불가능합니다. 두 WebAuthn 서버를 병합하면
이전 WebAuthn 서버(이전 의존 당사자 ID)에 등록된 패스키가 무용지물이 되어 사용자는 이러한
패스키로 로그인할 수 없습니다.

**해결 방법:**

여러 애플리케이션(예: 웹 앱과 네이티브 앱)이 있는 경우 항상 하나의 WebAuthn 서버만
사용하고 모든 앱에 대해 오직 하나의 의존 당사자 ID만 정의하세요. 이러한 앱 간의 연결은
위에서 설명한 단계에 따라 수행할 수 있습니다.

### 8.3 유효하지 않거나 접근할 수 없는 연결 파일

**실수:**

애플리케이션 개발을 시작하고 연결 파일을 구성하여 서버에 배포했습니다. 어떤 이유에서인지
여전히 오류 메시지가 나타나고 근본 원인을 찾을 수 없습니다.

**해결 방법:**

오류 메시지의 잠재적인 원인은 잘못된 형식이거나 도달할 수 없는 연결 파일일 수 있습니다.
서버에 연결 파일을 배포하기 전에 [iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios) 및 Android용으로
제공되는 도구를 통해 연결 파일의 유효성과 도달 가능성을 확인하는 것을 강력히
권장합니다(종종 이러한 파일은 Apple 및 Google 크롤러의 적절한 접근을 차단하는
[강력한 VPN](https://cybernews.com/best-vpn/most-secure-vpns/) 또는 방화벽 뒤에 있을 수
있습니다).

### 8.4 Apple CDN에 아직 캐시되지 않은 apple-app-site-association 파일

**실수:**

서버에 apple-app-site-association 파일을 배포했으며 테스트 기기에서 즉시 패스키 생성을
시작하고 싶습니다. 어떤 이유에서인지 패스키를 생성할 수 없으며 오류 메시지가 표시됩니다.

**해결 방법:**

이러한 오류 메시지의 이유는 iOS 기기가 의존 당사자의 유효성을 검사하기 위해
`apple-app-site-association` 파일을 다운로드하기 때문입니다. 이를 위해 iOS 기기는 서버에
직접 요청을 보내지 않고 대신 CDN을 사용합니다. 기기와 CDN은 파일이 성공적으로 검색된 후
`apple-app-site-association` 파일을 모두 캐시합니다. 이 캐싱 기능으로 인해
`apple-app-site-association` 파일의 새로운 변경 사항이 앱에 직접 반영되지 않습니다. CDN이
`apple-app-site-association` 파일을 캐시하는 데 최대 24시간이 걸릴 수 있습니다. 개발 중 이
제한을 우회하기 위해 의존 당사자 ID에 `?mode=developer`를 추가하여 캐싱을 완전히
비활성화할 수 있습니다(예: 의존 당사자 ID는 `acme.com?mode=developer`가 됩니다).

### 8.5 Android 에뮬레이터 및 API 버전 비호환성

**실수:**

Android 앱 개발을 시작하고 Android 에뮬레이터에서 테스트하려고 합니다. 어떤 이유에서인지
Android 에뮬레이터를 올바르게 설정했고 다른 앱은 에뮬레이터에서 원활하게 작동하는 것
같음에도 불구하고 오류 메시지가 표시됩니다.

**해결 방법:**

패스키 애플리케이션을 테스트할 때 Android 버전, Play 스토어 지원 및 API 버전이 주요 역할을
합니다. 게다가 Google 계정에 로그인되어 있어야 합니다. 자세한 내용은 문제 해결 섹션을
참조하세요.

## 9. 권장 사항

### 9.1 일반 권장 사항

우리의 전반적인 권장 사항은 애플리케이션 환경과 요구 사항에 따라 의존 당사자 ID를 신중하게
선택하는 것입니다. 아래에 가장 일반적인 사용 사례를 정리해 두었으나, 우리의 일반적인 권장
사항은 **루트 도메인을 의존 당사자 ID로 선택**하고 이러한 방식으로 인증을 구성해야 한다는
것입니다. Corbado를 사용하면 이 방식이 기본적으로 구성되어 있습니다(이는 모든 기술 설정에
원활한 패스키 인증을 제공하기 위한 우리의 접근 방식의 일부입니다. 우리의 UI 구성 요소와
SDK는 루트 도메인을 의존 당사자 ID로 사용할 준비가 되어 있습니다).

| 사례                                                                                                                                                                                                                                                                                                                                                     | 권장 사항                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **A) 하나의 루트 도메인이 있는 경우:**<br/><br/>예: acme.com<br/><br/>모든 애플리케이션과 인증이 이 루트 도메인이나 그 하위 도메인에서 실행됩니다.                                                                                                                                                                                                       | ✔️ 웹 앱이나 네이티브 앱에 어떠한 문제도 일으키지 않으므로 루트 도메인을 의존 당사자 ID로 선택하세요.                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| **B) 여러 루트 도메인이 있는 경우:**<br/><br/>예: kayak.com, kayak.co.uk, kayak.de<br/><br/>서로 다른 국제 최상위 도메인에서 사용자에게 서비스를 제공합니다. 미국의 경우 Kayak.com, 영국의 경우 kayak.co.uk를 사용하거나 동일한 사용자가 동일한 패스키로 로그인하도록 허용해야 하는 완전히 다른 루트 도메인이 있습니다.                                  | ⚠️ 웹 앱에서 패스키를 공유하려면 지정된 출처가 공통 RP ID를 사용할 수 있도록 `.well-known/webauthn`을 통해 관련 출처 요청을 구성해야 합니다(브라우저 지원 여부가 다르므로 호환성을 확인하세요). 대안으로 공통 인증 루트 도메인을 선택하세요.<br/><br/>✔️ 루트 연결 파일을 제어할 수 있는 한 네이티브 앱을 임의 개수의 루트 도메인에 연결할 수 있습니다.<br/><br/>❌ 나중에 웹사이트를 호스팅할 다른 루트 도메인으로 마이그레이션하려는 경우, 브랜드를 변경하고 도메인(의존 당사자 ID)을 변경해야 하므로 이미 생성된 패스키를 사용할 수 없게 됩니다. |
| **C) 아직 루트 도메인이 없으며 백엔드 전용 또는 공개 하위 도메인에서 실행 중입니다. 이 경우가 발생할 수 있는 몇 가지 상황:**<br/><br/>1. 루트 도메인을 제어할 수 없는(루트 도메인이 [https://publicsuffix.org/](https://publicsuffix.org/)에 나열됨) 무료로 사용 가능한 하위 도메인(예: CDN URL)에서 작업합니다.<br/><br/>2. 네이티브 앱에서 작업합니다. | ❌ 공개 하위 도메인에서는 루트 도메인의 루트 수준에서 연결 파일을 제어할 수 없습니다. 따라서 패스키가 네이티브 방식으로 작동하지 않습니다.<br/><br/>⚠️ 일부 서비스의 경우 이를 해결하는 유일한 방법은 CNAME을 정의하거나 자신만의 사용자 지정 루트 도메인을 얻을 수 있는 유료 플랜으로 변경하는 것입니다.                                                                                                                                                                                                                                           |

### 9.2 Corbado 사용 시 권장 사항

다음에서는 Corbado를 패스키 솔루션으로 사용할 때 올바른 의존 당사자 ID를 결정하고 연결
파일을 처리/호스팅하는 방법을 돕는 매우 구체적인 의사 결정 트리를 제공합니다.

첫 번째 결정은 당신이 개발 환경에 있는지 프로덕션 환경에 있는지입니다. 다음 결정 수준은
애플리케이션 환경을 기반으로 합니다: 네이티브 앱만 있는지 아니면 네이티브 앱과 웹 앱이
모두 있는지.

#### A) 개발

개발 환경에서는 신속하게 개발 및 테스트를 시작하고자 한다고 가정합니다. 나중에 서비스 런칭
시 의존 당사자 ID를 변경할 수 있습니다.

##### A1) 네이티브 앱 전용

- 의존 당사자 ID = `pro-XXX.frontendapi.cloud.corbado.io` 설정 (기본값)
- Corbado가 연결 파일을 호스팅해 줍니다
- DNS 관련 작업 필요 없음

##### A2) 네이티브 앱 및 웹 앱

웹 앱과 네이티브 앱을 동시에 테스트하는 것은 쉽지 않습니다.

**옵션 1:**

의존 당사자 ID = `pro-XXX.frontendapi.cloud.corbado.io` 설정(네이티브 앱 작동) 또는 의존
당사자 ID = `localhost` 설정(웹 앱 작동)

**옵션 2:**

네이티브 앱과 웹 앱이 동시에 작동할 수 있는 유일한 해결책은 로컬 리버스 프록시를 사용하는
것입니다(다소 편법적인 해결책입니다):

- 의존 당사자 ID = `acme-dev.com` 설정
- `acme-dev.com` =&gt; `pro-XXX.frontendapi.cloud.corbado.io`로 CNAME 설정
- 로컬 `/etc/hosts` 항목에 `localhost acme-dev.com` 추가
- `acme-dev.com` =&gt; `localhost:3000` (예시) 규칙을 사용하여 리버스 프록시(nginx) 추가

#### B) 프로덕션

프로덕션 환경에서는 하위 도메인을 의존 당사자 ID(예: `auth.acme.com`)로 사용하는 것으로
만족할지 아니면 루트 도메인을 의존 당사자 ID(예: `acme.com`)로 사용할지 결정해야 합니다.

##### B1) 의존 당사자 ID로서의 하위 도메인

###### B1.1) 네이티브 앱 전용

- 의존 당사자 ID = `auth.acme.com` 설정
- Corbado가 연결 파일을 호스팅해 줍니다
- `auth.acme.com` =&gt; `pro-XXX.frontendapi.cloud.corbado.io`로 CNAME 설정

###### B1.2) 네이티브 앱 및 웹 앱

- 의존 당사자 ID = `auth.acme.com` 설정
- Corbado가 연결 파일을 호스팅해 줍니다
- `auth.acme.com` =&gt; `pro-XXX.frontendapi.cloud.corbado.io`로 CNAME 설정 (Corbado의
  세션 관리를 사용하는 경우 쿠키 작동을 위해 필요함)

##### B2) 의존 당사자 ID로서의 루트 도메인

###### B2.1) 네이티브 앱 전용

- 의존 당사자 ID = `acme.com` 설정
- `acme.com/.well-known/<association file>`에 있는 자신의 서버에 연결 파일을 직접
  호스팅합니다
- DNS 관련 작업 필요 없음

###### B2.2) 네이티브 앱 및 웹 앱

- 의존 당사자 ID = `acme.com` 설정
- `acme.com/.well-known/<association file>`에 있는 자신의 서버에 연결 파일을 직접
  호스팅합니다
- Corbado의 세션 관리를 사용하는 경우 쿠키가 작동하도록 하려면 `auth.acme.com` =&gt;
  `pro-XXX.frontendapi.cloud.corbado.io`로 CNAME을 설정해야 합니다 (이 CNAME은 의존 당사자
  ID에 필요한 것이 아니라 전적으로 세션 관리에만 필요합니다)

다음 의사 결정 트리는 모든 구성 경로를 요약합니다.

## 10. 결론

의존 당사자 ID는 WebAuthn 및 패스키 기반 인증의 초석이며 강력한 피싱 저항성을 제공합니다.
이를 올바르게 구성하고, 도메인 일치의 복잡성을 이해하고, 네이티브 앱에 대해 올바른 배포를
보장하는 것이 중요합니다. 이 블로그 게시물에서는 이를 올바르게 설정하는 방법과 다양한
실수를 처리하는 방법을 보여주었습니다. rpID 구성이 견고해지면 패스키 생성 흐름과 패스키
로그인 흐름을 최적화하여 실제 채택을 유도하는 데 집중하세요. 네이티브 앱을 위한 패스키
설정에 대한 추가 정보가 필요하면 [Flutter](https://www.corbado.com/blog/flutter-passkeys-package)에서의 패스키에
대해 읽어보시기를 권장합니다.

추가 질문이 있거나 도움이 필요하면 주저하지 말고
[연락](https://bit.ly/passkeys-community)해 주세요.

## 자주 묻는 질문(FAQ)

### 의존 당사자 ID는 패스키 인증에서 어떻게 피싱을 방지하나요?

인증자는 브라우저의 실제 출처를 패스키에 저장된 의존 당사자 ID와 비교합니다. 공격자가 다른
도메인에 가짜 사이트를 호스팅하는 경우, 위조된 챌린지가 합법적인 RP ID를 주장하더라도 출처
불일치로 인해 인증이 자동으로 실패합니다. 이러한 바인딩으로 인해 paypal.com에 등록된
패스키는 paybal.com과 같은 유사 도메인에서 사용할 수 없습니다.

### 사용자가 이미 패스키를 등록한 후 WebAuthn 의존 당사자 ID를 변경하면 어떻게 되나요?

RP ID를 변경하면 각 자격 증명에 저장된 RP ID가 새 값과 더 이상 일치하지 않으므로 기존의
모든 패스키가 무효화됩니다. 유일한 예외는 새 RP ID가 이전 RP ID의 하위 도메인이거나
`.well-known/webauthn`을 통해 관련 출처 요청(Related Origin Requests)이 구성된
경우뿐입니다. 이 돌이킬 수 없는 문제를 피하려면 처음부터 루트 도메인을 RP ID로 선택하세요.

### apple-app-site-association 파일을 배포한 후 즉시 iOS 패스키가 작동하지 않는 이유는 무엇인가요?

iOS는 서버에서 직접 apple-app-site-association 파일을 가져오지 않습니다. Apple의 CDN을
사용하며, 새로 배포되거나 업데이트된 파일을 캐시하는 데 최대 24시간이 걸릴 수 있습니다.
개발 중에는 의존 당사자 ID에 `?mode=developer`를 추가하여 캐싱을 완전히 우회하세요.

### 패스키의 의존 당사자 ID로 하위 도메인이나 루트 도메인 중 어느 것을 사용해야 하나요?

하위 도메인에서 생성된 패스키는 해당 루트의 모든 하위 도메인에서 인증할 수 있으므로 루트
도메인(예: acme.com)을 사용하는 것이 좋습니다. 하위 도메인 RP ID는 패스키 사용을 해당 하위
도메인과 그 하위 항목으로 제한하므로, 나중에 도메인 간 흐름을 방해할 수 있습니다. acme.com
및 acme.co.uk와 같은 여러 루트 도메인이 있는 경우 `.well-known/webauthn`을 통해 관련 출처
요청을 구성하여 패스키를 재사용할 수 있도록 하세요.
