# Baron SSO PKCE 모바일 RP Headless 계약 확인 요청

## 이슈 제목

`[API Contract Request] PKCE 모바일 RP의 Headless 전화번호 로그인 지원 방식 확인 요청`

## 배경

신규 Flutter 앱 `TDC114PLUS`를 Baron SSO의 PKCE 공개 클라이언트 RP로 등록했습니다.

- Client ID: `39d6190d-72f6-4a58-a84f-cdc5ece3e8af`
- Redirect URI: `https://114.hmac.kr/auth/callback`
- Client Secret: 없음
- OIDC issuer: `https://sso.hmac.kr/oidc`

앱의 로그인 UX는 아래 순서를 사용합니다.

1. 사용자가 앱에서 전화번호로 로그인을 요청
2. Baron SSO가 문자 또는 메일로 승인 링크 발송
3. 사용자가 링크 클릭
4. 앱이 승인 상태를 확인
5. OIDC authorization code + PKCE로 앱 세션 생성

## 확인된 계약

Swagger의 아래 API는 `client_assertion`을 필수로 요구합니다.

- `POST /api/v1/auth/headless/phone-login`
- `POST /api/v1/auth/headless/link/poll`

`client_assertion`은 `private_key_jwt`로 설명되어 있습니다. 그러나 TDC114PLUS는 Client Secret이나 개인키를 안전하게 보관할 수 없는 PKCE 공개 모바일 앱입니다.

## 문제점

모바일 APK에 `private_key_jwt` 서명용 개인키를 포함하면 추출될 수 있으므로 공개 클라이언트 보안 모델에 맞지 않습니다.

OIDC Discovery에서는 token endpoint 인증 방식 `none`과 PKCE S256을 지원하므로 authorization code 교환은 가능하지만, 그 앞의 headless API 호출 방법이 현재 계약만으로는 확정되지 않습니다.

## 요청 사항

PKCE 공개 모바일 RP에서 아래 값을 획득하고 headless 로그인을 진행하는 공식 절차를 명세해 주시기 바랍니다.

1. `login_challenge` 획득 절차
2. `client_assertion` 생략 가능 여부
3. 생략이 불가능한 경우 단기·1회성 assertion 발급 endpoint
4. assertion의 issuer, subject, audience, 만료시간, 서명 알고리즘
5. `phone-login -> link/poll -> redirectTo -> callback -> token` 전체 순서
6. 각 단계의 Request/Response 예시와 오류 코드

## 제안 가능한 방식

- 모바일 PKCE RP에 한해 headless API에서 assertion 대신 등록된 Client ID, PKCE transaction, 짧은 TTL의 서버 challenge를 검증
- Baron SSO가 모바일 RP용 단기·1회성 assertion을 발급
- confidential 중계 서버를 별도로 두고 해당 서버만 `private_key_jwt`를 생성

## 완료 기준

- 개인키를 APK에 저장하지 않고 headless API를 호출할 수 있음
- 승인 완료 후 `https://114.hmac.kr/auth/callback`으로 authorization code가 전달됨
- 앱이 PKCE verifier로 token endpoint에서 토큰을 교환할 수 있음
