크라우니AI브라우저 패스키 SSO — 0단계(선결 실증)
개요
크롬식 "이 사용자로 로그인?→확인" 원터치 SSO 5단계 계획의 0단계.
목표: AASA + Associated Domains 구성 → rpId=crowny.org 확정 → 크라우니AI브라우저(iOS) WKWebView에서 패스키 등록/어설션 스모크가 실제로 뜨는지 실증.
확정 값
- 앱 Xcode:
/Users/ef/CrownyBrowser/ios/xcode/CrownyAI.xcodeproj (스킴/타깃 CrownyAI, ObjC CrownyAI.m)
- Team ID:
LQ83M5TL9S · Bundle ID: org.crowny.crownyai · iOS 타깃 16.0
- AASA appID:
LQ83M5TL9S.org.crowny.crownyai
- apex crowny.org =
/Users/ef/crowny-ai/server.js (Node, :9852)
- 딥링크:
crownyai://open?url=<encoded> → WKWebView 로드
- 시뮬레이터: iPhone 16 Pro / 17 Pro / 17 부팅됨
완료 (자동화·검증됨)
- AASA 서빙: crowny-ai/server.js 최상단(인증 이전)에
/.well-known/apple-app-site-association 라우트 추가.
본문
{"webcredentials":{"apps":["LQ83M5TL9S.org.crowny.crownyai"]}},
application/json, 리다이렉트0.
검증: 로컬:9852·apex https://crowny.org 둘 다 200, 랜딩 회귀 200. 동반=
crowny-ai/패스키AASA.한선(자가검증 ok).
- iOS 엔타이틀먼트:
ios/xcode/CrownyAI/CrownyAI.entitlements 신규 = com.apple.developer.associated-domains: [webcredentials:crowny.org].
pbxproj Debug·Release 두 타깃 buildSettings에
CODE_SIGN_ENTITLEMENTS 결선.
- rpId=crowny.org 확정 + WebAuthn 스모크 페이지:
crowny-ai/public/passkey-smoke.html
(create/get, rpId=crowny.org, ES256+RS256, UVPA 체크, 콘솔 로그). 라이브 https://crowny.org/passkey-smoke.html 200.
동반=
crowny-ai/public/passkey-smoke.한선(등록/인증 옵션·rpId유효 자가검증 apex/sub/phish ok).
시뮬레이터 실증 결과 (2026-08-01, iPhone 16 Pro / iOS 18.4)
빌드/설치/실행 OK: generic 시뮬 destination + ad-hoc 서명(CODE_SIGN_IDENTITY="-", 무팀). BUILD SUCCEEDED, 설치·실행 확인.
env 훅(CrownyAI.m didFinishLaunching, CROWNY_SMOKE_URL 게이트 — 기본동작 무변경): SpringBoard 딥링크 확인 없이 앱 내부 WKWebView로 스모크 페이지 직접 로드.
핵심 실증(스크린샷 /tmp/pk-shots/02-smoke.png):
origin=https://crowny.org (rpId=crowny.org 일치)
WebAuthn 지원: true ← 이 앱 WKWebView가 패스키 API 지원(전제 충족)
플랫폼 인증자(UVPA): false
자동 create() → NotAllowedError(NotSupported 아님 = API 경로 살아있음, 제스처/인증자 정책 거부)
UVPA=false는 시뮬레이터 한계: Features>Face ID>Enrolled 켜도 여전히 false(04-uvpa.png). iOS 시뮬레이터엔 WebAuthn용 플랫폼 인증자(Secure Enclave)가 없어 실제 패스키 생성 불가 — 알려진 제약, 설정 결함 아님.
자동화 한계: 시뮬이 simctl 헤드리스 부팅이라 System Events가 창 미인식(windows=0) → cliclick 좌표 탭 불가. 메뉴 자동화(Face ID enroll)만 가능.0단계 판정: GO (조건부)
- 전제 충족: 앱 WKWebView가 패스키를 지원하고(지원:true), origin·rpId·AASA 전부 올바르게 배선됨. API 경로 라이브(create가 NotSupported 아님).
- 실기기 필요분: 전체 세리머니(시트 출현+생체+크리덴셜 생성)와 associated-domains 엔타이틀먼트 임베드는 실 iPhone(Face ID/Touch ID+iCloud Keychain) + 프로비저닝 서명 빌드에서만 검증 가능. 시뮬레이터로는 불가.
- ad-hoc 시뮬 빌드는 associated-domains 엔타이틀먼트를 드롭(codesign 확인
<dict></dict>) — 프로비저닝 빌드(dev portal에 App ID capability 활성) 필요. 동일-origin 웹 패스키(지원:true)는 엔타이틀먼트 독립이라 이번 실증엔 무영향.
산출물
- crowny-ai/server.js AASA 라우트 + crowny-ai/패스키AASA.한선
- crowny-ai/public/passkey-smoke.html + passkey-smoke.한선
- ios/xcode/CrownyAI/CrownyAI.entitlements + pbxproj 결선
- ios/xcode/CrownyAI/CrownyAI.m env 훅(CROWNY_SMOKE_URL, 게이트드)
유의점(설계 근거)
- 동일-origin 웹 WebAuthn(페이지=crowny.org, rpId=crowny.org)은 iOS16+ WKWebView에서 엔타이틀먼트 독립으로 동작(웹 origin 기반).
- Associated Domains(webcredentials)는 자동완성·크로스오리진·네이티브 패스키용 — 카스케이드 SSO 확장의 전제. AASA+엔타이틀먼트로 이 링크를 구성.
- 시뮬레이터 패스키 완주는 Face ID 등록(Features>Face ID>Enrolled)+Matching Face UI 필요 — 시트 출현까지 자동, 최종 생체 확인은 시뮬 UI 상호작용.
다음 단계(승인된 계획)
1단계 IdP(:9610) WebAuthn 등록/검증(공개키 IdP 저장) · 2단계 모드1 동의버튼 원터치 tele 종단 · 3단계 모드2 패스키 step-up 금융 · 4단계 확산+폴백/복구/로그아웃.