23 KiB
휴대폰 번호 단독 로그인 기술 검토 및 구현 대안
작성일: 2026-06-23
1. 목적
본 문서는 Baron SSO에서 논의된 "휴대폰 번호만 입력하면 즉시 로그인되는 방식"의 기술 구현안을 검토하고, 각 프로세스에서 어떤 데이터가 생성되는지, 해당 단계가 표준 기술에 해당하는지, 비표준 또는 우회 구현이라면 어떤 위험이 있는지 정리한다.
검토 범위는 다음 이슈와 현재 코드 기준 구현 흔적을 포함한다.
- Gitea Issue #1241:
[Feature/API] Headless 폰번호 전용 로그인 API 구현 - Gitea Issue #1245:
[Research/Design] 기존 QR코드/링크 로그인 아키텍처 분석 및 Headless 폰번호 로그인 적용 설계안 - Gitea Issue #1247:
[Architecture/Design] Baron Backend ↔ Ory Kratos 인터랙션 분석 및 폰번호 로그인 세션 발급 아키텍처 - Gitea Issue #1248:
[Feature] 휴대폰 번호 입력만으로 즉시 로그인 기능 구현 (인증 코드 없는 Passwordless) - Gitea Issue #1252:
[Feature] userfront 내 휴대폰 번호 입력 전용 초간결 로그인 화면/모드 구현 - Gitea Issue #1258:
[Feature] userfront 내 휴대폰 번호 전용 독립 라우트(connect) 신설 및 비인가/로그아웃 리다이렉션 전면 일괄 전환
2. 결론 요약
휴대폰 번호만으로 로그인시키는 방식은 사용자 인증 관점에서 표준 로그인 방식으로 보기 어렵다. 휴대폰 번호는 사용자 식별자(identifier)일 수는 있지만, 그 자체로 사용자 본인성 또는 번호 소유를 증명하는 인증 수단(authenticator)이 아니다.
현재 논의된 구현안은 크게 세 가지로 나뉜다.
| 방식 | 요약 | 표준성 판단 | 권장 여부 |
|---|---|---|---|
| Kratos Admin 세션 직접 발급 | 번호로 사용자를 찾은 뒤 관리자 API로 세션 생성 | 제품 내부 Admin API 사용일 수 있으나 사용자 인증 우회 | 비권장 |
| Courier 인터셉트/코드 자동 제출 | Kratos code login을 시작하고 발송 코드를 백엔드가 가로채 제출 | Kratos code login 자체는 표준 플로우이나 코드 소유자 확인을 제거한 우회 | 비권장 |
| Headless client assertion + 폰번호 | RP 클라이언트 JWT는 검증하고 사용자는 번호만 입력 | 클라이언트 인증은 표준 JWT 기반일 수 있으나 사용자 인증은 부재 | 제한적/보완 필수 |
보완 없이 운영하면 전화번호를 아는 사람 또는 내부 시스템 접근자가 타인의 세션을 만들 수 있는 구조가 된다. 따라서 최소한 SMS OTP, FIDO2/WebAuthn, 기기 바인딩, 사전 등록 단말 인증, 관리자 승인, 네트워크 제한 중 하나 이상의 실질적인 사용자 인증 또는 환경 인증이 필요하다.
3. 현재 코드 기준 상태
현재 코드에서 확인되는 관련 위치는 다음과 같다.
| 영역 | 파일 | 확인 내용 |
|---|---|---|
| Backend route | backend/cmd/server/main.go |
/api/v1/auth/headless/link/init, /api/v1/auth/headless/link/poll 등록 |
| Headless link init/poll | backend/internal/handler/auth_handler.go |
HeadlessLinkInit, HeadlessLinkPoll, startHeadlessPhoneLink 구현 |
| Kratos code login 시작 | backend/internal/service/ory_service.go |
InitiateLinkLogin에서 Kratos code login flow 시작 |
| Kratos code 제출 | backend/internal/service/ory_service.go |
VerifyLoginCode에서 self-service/login?flow=...에 code 제출 |
| Courier relay | backend/internal/handler/auth_handler.go |
HandleKratosCourierRelay에서 login code를 Redis에 저장하거나 QR 흐름을 자동 검증 |
| Admin 세션 직접 발급 함수 | backend/internal/handler/auth_handler.go |
issueKratosSession 함수는 있으나 현재 검색 기준 호출부는 없음 |
| OryProvider IssueSession | backend/internal/service/ory_service.go |
IssueSession은 domain.ErrNotSupported 반환 |
| Userfront phone-only route | userfront/lib/main.dart, userfront/lib/features/auth/presentation/login_screen.dart |
현재 검색 기준 connect, phone_only, phone-login 직접 구현은 확인되지 않음 |
따라서 이슈 #1248에서 제안된 POST /api/v1/auth/phone-login 직접 API는 현재 코드상 활성 라우트로 확인되지 않는다. 실제로 가까운 구현은 /api/v1/auth/headless/link/init 및 /poll 기반의 headless link 흐름이다.
4. 프로세스별 데이터 생성 및 표준성 검토
4.1 휴대폰 번호 입력 및 정규화
프로세스:
- 사용자가 휴대폰 번호를 입력한다.
- Userfront 또는 Backend가 하이픈, 공백 등을 제거한다.
- Backend가
normalizePhoneForLoginID계열 로직으로 E.164에 가까운 로그인 식별자로 변환한다. - 변환된 값으로 Kratos identity 또는 로컬 원장을 조회한다.
생성 또는 변환되는 데이터:
| 데이터 | 예시 | 생성 주체 | 용도 |
|---|---|---|---|
| Raw phone number | 010-1234-5678 |
사용자/Userfront | 입력값 |
| Sanitized phone | 01012345678 |
Backend | 정규화 전처리 |
| Login ID | +821012345678 |
Backend | Kratos credentials identifier 조회 |
| Identity ID | UUID | Kratos/Admin 조회 | 최종 subject 후보 |
표준성 판단:
- 전화번호 E.164 정규화는 표준적인 식별자 정규화에 해당한다.
- 그러나 전화번호 입력만으로 사용자를 인증하는 것은 표준 인증 기술이 아니다.
- 이 단계는 "식별" 단계이지 "인증" 단계가 아니다.
위험:
- 전화번호는 공유되거나 유출되기 쉽다.
- 번호 입력 성공/실패 응답이 다르면 사용자 존재 여부 열람(user enumeration)이 가능하다.
- 가입자 번호 재할당, 퇴사자 번호 회수, 가족/공용 단말 사용 같은 실제 운영 문제가 인증 실패로 이어질 수 있다.
권장 보완:
- 존재 여부 응답을 일반화한다.
- 번호는 반드시 소유 증명 단계로 이어지게 한다.
- 사용자 원장에는 E.164, 국가 코드, 원본 표시값을 분리 저장한다.
4.2 사용자 존재 여부 조회
프로세스:
- Backend가 정규화된 전화번호를 사용해
UserExists또는 Kratos Admin identity 조회를 수행한다. - 사용자가 없으면 오류를 반환한다.
- 사용자가 있으면 다음 세션 생성 단계로 진행한다.
생성 또는 조회되는 데이터:
| 데이터 | 생성/조회 주체 | 용도 |
|---|---|---|
| credentials identifier | Backend | Kratos identity 검색 조건 |
| identity id | Kratos | OIDC subject 또는 세션 대상 |
| user exists boolean | Backend | 로그인 진행 여부 |
표준성 판단:
- IdP 원장에서 identifier로 identity를 조회하는 행위 자체는 일반적이다.
- 다만 이 결과만으로 로그인 성공을 허용하면 인증 요소가 없다.
위험:
- 공격자가 전화번호 목록으로 등록 여부를 확인할 수 있다.
- 내부 API가 열려 있으면 대량 스캐닝이 가능하다.
권장 보완:
- rate limit, IP 제한, WAF 룰, device attestation 등을 추가한다.
404 User not registered대신 일반 메시지를 사용한다.- 감사 로그에는 입력 원문이 아닌 마스킹된 번호와 해시를 남긴다.
4.3 Kratos Admin 세션 직접 발급 방식
이슈 #1248 초반 설계에서는 다음 흐름이 제안되었다.
POST /api/v1/auth/phone-login요청을 받는다.- Backend가 전화번호로 Kratos identity ID를 찾는다.
- Backend가 Kratos Admin API로 해당 identity에 대한 세션을 직접 생성한다.
- 세션 토큰을 Userfront에 반환한다.
생성되는 데이터:
| 데이터 | 생성 주체 | 저장/전달 위치 |
|---|---|---|
| Kratos session id | Kratos | Kratos DB, Backend 응답 처리 |
| Kratos session token | Kratos | Backend 응답, Userfront token store |
| authenticated_at | Kratos | 세션 메타데이터 |
| AAL | Backend 요청/Kratos | 세션 보증 수준 |
표준성 판단:
- 관리자 API를 통한 세션 생성 기능 자체가 제품 기능일 수는 있다.
- 그러나 사용자가 아무 인증 수단도 제시하지 않았는데 관리자 권한으로 세션을 만들어 주는 것은 사용자 인증 표준 흐름이 아니다.
- OAuth2/OIDC 관점에서도 인증 서버가 사용자의 본인성을 확인하지 않은 채 login challenge를 accept하면 인증 의미가 훼손된다.
현재 코드 상태:
issueKratosSession(ctx, identityID)함수가 존재한다.- 현재 검색 기준 이 함수의 호출부는 확인되지 않는다.
OryProvider.IssueSession은domain.ErrNotSupported를 반환한다.
위험:
- Backend 권한 탈취 시 임의 사용자 세션 발급이 가능하다.
- 감사 로그에는 "정상 로그인"처럼 남을 수 있으나 실제 사용자 행위가 아니다.
- AAL1로 표시되더라도 실질적 authenticator가 없으므로 보증 수준 해석이 왜곡된다.
권장 보완:
- 운영 로그인 경로로 사용하지 않는다.
- 필요한 경우 break-glass 관리자 지원 기능으로만 제한하고, 별도 승인/티켓/감사/만료 정책을 둔다.
- 관리자 세션 발급 기능은 feature flag로 기본 비활성화한다.
4.4 Courier 인터셉트 및 Code Claim 방식
이슈 #1248 후반 코멘트 및 #1245, #1247에서는 실제 구현에 가까운 방식으로 Courier 인터셉트가 설명되어 있다.
프로세스:
- Backend가 전화번호를 기반으로 Kratos code login flow를 시작한다.
- Kratos가 SMS 또는 email courier 발송을 시도한다.
- Kratos Courier Webhook이 Backend의 relay endpoint를 호출한다.
- Backend가
template_data.login_code를 추출한다. - Backend가 추출한 code를 즉시 Kratos
self-service/login?flow=...에 제출한다. - Kratos가 session token을 발급한다.
- Backend가 Redis pending session을 success로 갱신한다.
- Poll 또는 후속 처리에서 Userfront/RP가 로그인 완료를 확인한다.
생성되는 데이터:
| 단계 | 데이터 | 생성 주체 | 저장 위치 |
|---|---|---|---|
| flow init | flow id | Kratos | Redis login_code_flow:{loginID} |
| pending 생성 | pendingRef | Backend | Redis enchanted_session:{pendingRef} |
| pending 매핑 | loginID -> pendingRef | Backend | Redis login_code_pending:{loginID} |
| courier | login_code | Kratos | Webhook payload |
| code 저장 | normalized login code | Backend | Redis login_code_value:{pendingRef} |
| code verify | session token, session id | Kratos | Redis session payload 또는 응답 |
| audit | login event | Backend | Audit DB |
표준성 판단:
- Kratos code login flow 자체는 IdP의 정상 self-service login flow이다.
- Courier Webhook을 통해 메시지를 발송 대행하는 구조도 제품 통합 방식으로 볼 수 있다.
- 그러나 사용자가 수신한 OTP/SMS를 직접 확인하지 않고, 서버가 코드를 가로채 자동 제출하는 것은 OTP의 본래 보안 속성인 "사용자 소유 채널 확인"을 제거한다.
- 따라서 전체 로그인 방식은 표준 passwordless/SMS OTP 인증으로 보기 어렵다. 표준 기술을 사용해 비표준 인증 우회를 구성한 형태에 가깝다.
위험:
- 전화번호만 알면 세션 발급까지 진행될 수 있다.
- SMS 비용을 줄이는 대신 소유 증명이 사라진다.
- Courier relay가 내부 인증 없이 외부에서 호출 가능하면 코드 주입 또는 흐름 교란이 가능하다.
- Redis pending key 탈취 시 승인 흐름이 오염될 수 있다.
권장 보완:
- Courier relay endpoint는 내부 네트워크 또는 mTLS, shared secret, HMAC signature로 보호한다.
- code는 저장하지 않고 즉시 처리하되, 저장이 필요하면 TTL을 매우 짧게 유지한다.
- 자동 제출은 운영 사용자 로그인에 사용하지 않고, 테스트/개발 dry-run에 한정한다.
- 실서비스에서는 사용자에게 SMS OTP를 전달하고 사용자가 입력하도록 한다.
4.5 Headless client assertion + 폰번호 로그인
이슈 #1241은 RP가 client_assertion을 제출하고, 사용자는 전화번호만 전달하는 headless API를 제안한다.
프로세스:
- RP가
client_id,client_assertion,phoneNumber,login_challenge를 Backend에 제출한다. - Backend가 Hydra login request를 조회한다.
- Backend가 RP의 JWT client assertion을 JWKS로 검증한다.
- Backend가 전화번호로 사용자를 조회한다.
- Backend가 세션 발급 또는 code login flow를 진행한다.
- Backend가 Hydra
AcceptLoginRequest를 호출한다. - RP는
redirectTo또는 OIDC authorization code 흐름을 이어간다.
생성되는 데이터:
| 데이터 | 생성 주체 | 표준 기술 여부 |
|---|---|---|
| client assertion JWT | RP | OAuth2 JWT client authentication 계열 |
| JWKS key | RP | JOSE/JWK 표준 |
| login challenge | Hydra | Ory Hydra/OIDC 로그인 플로우 |
| Kratos subject | Kratos | IdP subject |
| redirectTo | Hydra | OAuth2/OIDC authorization redirect |
표준성 판단:
client_assertion과 JWKS 검증은 OAuth2/OIDC에서 사용하는 표준적인 클라이언트 인증 방식에 가깝다.- Hydra login challenge, authorization code, PKCE는 표준 OIDC/OAuth2 기술이다.
- 그러나 이 검증은 RP 클라이언트가 신뢰 가능한지를 확인할 뿐, 최종 사용자가 전화번호 소유자임을 증명하지 않는다.
- 따라서 사용자 인증 단계는 여전히 비표준 또는 불충분한 상태다.
위험:
- 신뢰된 RP가 잘못 구현되거나 침해되면 임의 전화번호 로그인 시도가 가능하다.
client_assertion을 사용자 인증으로 오해할 수 있다.- RP별 정책 편차가 커지면 SSO의 인증 보증 수준이 불명확해진다.
권장 보완:
- headless API는 confidential client만 허용한다.
- RP별로
headless_phone_login_enabled같은 명시적 allowlist를 둔다. - 사용자 인증은 별도로 SMS OTP, WebAuthn, 앱 푸시 승인, 사전 등록 단말 증명 중 하나를 요구한다.
acr또는amrclaim에 실제 인증 방식을 명확히 기록한다.
4.6 Hydra AcceptLoginRequest 및 OIDC 연동
프로세스:
- Backend가 Hydra login challenge를 조회한다.
- 인증 완료로 판단한 subject를 결정한다.
- Backend가
AcceptLoginRequest(login_challenge, subject)를 호출한다. - Hydra가 RP로 돌아갈
redirectTo를 반환한다. - RP는 authorization code 또는 token 교환을 수행한다.
생성되는 데이터:
| 데이터 | 생성 주체 | 용도 |
|---|---|---|
| subject | Backend/Kratos | OIDC user identifier |
| redirectTo | Hydra | RP redirect |
| authorization code | Hydra | token endpoint 교환 |
| id/access/refresh token | Hydra | RP 세션 수립 |
표준성 판단:
- Hydra의 OAuth2/OIDC 처리 자체는 표준 흐름이다.
- PKCE가 적용된 authorization code flow는 표준 보안 권고에 부합한다.
- 단, Hydra가 accept하는 전제인 "사용자 인증 완료"가 비표준 방식이면 전체 로그인 보증 수준은 낮아진다.
권장 보완:
- 비표준 인증으로 accept한 경우
amr=["phone_identifier_only"]처럼 별도 표시를 한다. - 민감 RP에는 해당
amr을 허용하지 않는다. - RP별 required ACR 정책을 둔다.
4.7 감사 로그 및 로그아웃 바인딩
프로세스:
- 로그인 성공 후 Backend가 audit log를 기록한다.
- OIDC accept 또는 consent granted 이벤트에
session_id,client_id,user_id를 남긴다. - 로그아웃 시 audit log에서 session-client binding을 복원한다.
- Hydra refresh revoke 및 backchannel logout을 수행한다.
생성되는 데이터:
| 데이터 | 생성 주체 | 용도 |
|---|---|---|
| audit event | Backend | 로그인/승인 이력 |
| session_id | Kratos/Backend | 세션 식별 |
| client_id | Hydra/RP | RP 식별 |
| consent event | Backend | RP 동의/연동 추적 |
표준성 판단:
- Backchannel Logout, refresh token revoke는 OIDC/OAuth2 생태계의 표준적 세션 관리 기술이다.
- 감사 로그 기반 바인딩 복원은 내부 구현 전략이며 표준 자체는 아니다.
위험:
- 감사 로그 누락 또는 비동기 지연 시 로그아웃 전파 누락 가능성이 있다.
- 비표준 로그인으로 생성된 세션과 표준 로그인 세션이 같은 수준으로 취급될 수 있다.
권장 보완:
- 세션-클라이언트 바인딩은 감사 로그 외에도 명시적 저장소를 둘지 검토한다.
- 비표준 로그인 세션에는 별도
login_method,amr,risk_level을 남긴다.
5. 표준 기술과 비표준 요소 매핑
| 구성 요소 | 적용 기술 | 표준/비표준 판단 | 비고 |
|---|---|---|---|
| 전화번호 E.164 정규화 | E.164 형식 | 표준 | 식별자 정규화 |
| Kratos self-service code login | Ory Kratos code login | 제품 표준 기능 | 사용자가 코드를 확인해야 인증 의미가 있음 |
| SMS OTP | One-time code over SMS | 일반적 MFA/passwordless 구현 | SIM swap, SMS 탈취 위험은 별도 존재 |
| Courier Webhook | Ory Courier 통합 | 제품 통합 기능 | 발송 대행은 가능 |
| Courier code 자동 추출/제출 | 내부 우회 | 비표준 | 사용자 소유 채널 확인 제거 |
| Kratos Admin 세션 직접 생성 | Admin API | 운영 인증에는 비표준/고위험 | break-glass 외 비권장 |
| OAuth2 client assertion JWT | JWT client authentication | 표준 계열 | 클라이언트 인증이지 사용자 인증이 아님 |
| JWKS | JOSE/JWK | 표준 | 키 배포/검증 |
| Hydra login challenge accept | OIDC/OAuth2 | 표준 | 인증 전제가 중요 |
| Authorization Code + PKCE | OAuth2/OIDC | 표준 | public client 권장 흐름 |
| Backchannel Logout | OIDC Back-Channel Logout | 표준 | RP 지원 필요 |
| Refresh token revoke | OAuth2 Token Revocation | 표준 | RP/AS 구현 정책 필요 |
6. 대체 기술 및 보완 제안
6.1 권장안 A: SMS OTP 기반 폰 로그인
사용자 UX:
- 전화번호 입력
- SMS OTP 수신
- OTP 입력
- Kratos code login verify
- Hydra accept
장점:
- 전화번호 소유 확인이 가능하다.
- 기존 Kratos code login 구조를 가장 자연스럽게 사용한다.
- 사용자 인증 방식이 명확하다.
보완:
- OTP TTL 3~5분
- 재전송 제한
- 번호별/IP별 rate limit
- 실패 횟수 제한
- SIM swap 위험 안내 및 고위험 RP 추가 인증
6.2 권장안 B: WebAuthn/FIDO2 패스키
사용자 UX:
- 전화번호 또는 계정 식별자 입력
- 브라우저/OS 패스키 인증
- Kratos 세션 발급
- Hydra accept
장점:
- 피싱 저항성이 높다.
- SMS보다 강한 사용자 인증이다.
- 반복 로그인 UX가 빠르다.
보완:
- 초기 등록 절차 필요
- 분실/기기 교체 복구 정책 필요
6.3 권장안 C: 사내 전용 단말/키오스크 제한 모드
휴대폰 번호 단독 UX를 반드시 유지해야 한다면 일반 로그인으로 보지 말고 "통제된 환경의 단말 로그인"으로 분리한다.
필수 조건:
- 전용 단말 인증서 또는 mTLS
- 고정 네트워크/IP allowlist
- 단말별 client credential
- 단말 등록/폐기 관리
- 사용자별 허용 RP 제한
- 짧은 세션 TTL
- 민감 기능 재인증
판단:
- 사용자는 전화번호로 식별하고, 실제 인증은 단말/네트워크/관리 정책이 대신 수행하는 구조다.
- 이 경우에도
amr에는trusted_device_phone_identifier처럼 일반 로그인과 다른 방식을 명시해야 한다.
6.4 권장안 D: 모바일 앱 푸시 승인
사용자 UX:
- PC/키오스크에서 전화번호 입력
- 등록된 모바일 앱으로 푸시 승인
- 사용자가 앱에서 승인
- Backend가 Kratos/Hydra 흐름 완료
장점:
- 빠른 UX를 유지하면서 사용자 소유 기기 확인이 가능하다.
- QR 로그인과 유사한 승인 모델을 재사용할 수 있다.
보완:
- 앱 등록/기기 바인딩 필요
- 푸시 피로 공격 방지를 위한 rate limit와 number matching 필요
6.5 권장안 E: 공통 승인 화면 적용
현재 작업 트리에 있는 approval/info, approval/reject, LoginApprovalScreen 계열 변경은 QR/링크 같은 비표준 로그인에 승인 전 정보를 보여주는 보완책이다.
권장 적용:
- QR, 링크, headless link 모두 공통 승인 화면 사용
- 승인 전에 요청 서비스, 기기, IP, 시간 표시
내 요청이 아닙니다선택 시 pending 상태를rejected또는blocked로 변경- 승인 거절 이벤트를 감사 로그로 남김
주의:
- 승인 화면은 "보완책"이지 전화번호 단독 로그인의 인증 부재를 완전히 해결하지 않는다.
- 사용자가 직접 승인하는 별도 소유 기기나 세션이 있을 때 의미가 있다.
7. 운영 정책 제안
7.1 기본 정책
- 휴대폰 번호만으로 세션을 발급하는 API는 운영 기본 경로로 노출하지 않는다.
POST /api/v1/auth/phone-login형태의 단일 요청 즉시 로그인은 금지한다.- Courier code 자동 제출은 개발/테스트 dry-run 또는 제한된 내부 시나리오로만 허용한다.
- 모든 비표준 로그인에는
login_method,amr,risk_level,client_id,device_id를 남긴다.
7.2 RP별 정책
- RP별로 허용 가능한 인증 강도를 설정한다.
- 민감 RP는 SMS OTP 이상 또는 WebAuthn을 요구한다.
- headless 로그인 허용 RP는 별도 allowlist와 보안 심사를 거친다.
7.3 감사 및 탐지
- 전화번호 기반 로그인 시도는 성공/실패 모두 감사 로그에 남긴다.
- 동일 IP의 다수 번호 시도, 동일 번호의 반복 실패, 짧은 시간 내 다수 RP 로그인은 탐지 대상으로 둔다.
- 비표준 로그인으로 발급된 세션은 대시보드와 관리자 화면에서 구분 표시한다.
8. 권장 구현 방향
- 폰번호 단독 즉시 로그인은 구현하더라도 기본 비활성 feature flag로 둔다.
- 운영 사용자 로그인에는 SMS OTP 또는 WebAuthn을 붙인다.
- 키오스크/전용 단말 요구사항이라면 별도 라우트와 별도 보증 수준으로 분리한다.
- Hydra accept 시
amr/acr를 명확히 기록하고 RP 정책과 연결한다. - Courier relay는 내부망 또는 서명 검증으로 보호한다.
- 공통 승인 화면을 QR/링크/headless link에 적용해 사용자가 요청 정보를 확인하게 한다.
- 표준 로그인과 비표준 로그인의 감사 로그, 세션 TTL, RP 접근 권한을 분리한다.
9. 최종 판단
휴대폰 번호 단독 로그인은 "간편한 식별 UX"로는 사용할 수 있지만, 그 자체를 사용자 인증으로 간주하면 안 된다.
Baron SSO의 표준 인증 경로로 채택하려면 다음 중 하나가 반드시 추가되어야 한다.
- SMS OTP 또는 음성 OTP
- WebAuthn/FIDO2 패스키
- 등록된 모바일 앱 푸시 승인
- 사내 전용 단말 인증 및 네트워크 제한
- 관리자 승인 또는 업무 시스템 내 2차 승인
이 중 아무 것도 없는 phoneNumber -> session 구조는 표준 인증이 아니라 인증 우회에 가깝다. 따라서 운영 적용 시에는 "비표준 저보증 로그인"으로 명시하고, 접근 가능한 RP와 기능 범위를 제한해야 한다.