Skip to content

target_session_token PoP (same-device merge)

같은 user-agent 에 두 logi 계정 세션이 모두 활성일 때 OTP 없이 merge 하는 PoP 자격증명. cross-device 케이스는 OTP 사용.

흐름

  1. Target(B) 세션에서 토큰 발급 → raw 문자열 1회 노출 (5분 TTL).
  2. 같은 브라우저 frontend 가 토큰을 Requester(A) 세션으로 전달 (postMessage/sessionStorage 등 자유).
  3. Requester(A) 가 /me/mergetarget_session_token 제출 → atomic single-use 소비.
  4. Audit: identity_links.merged_via = "session_token".

API

토큰 발급

http
POST /api/v1/me/merge/session-token
Authorization: <target 세션 쿠키 또는 PAK>
Content-Type: application/json

{ "idempotency_key": "uuid-optional" }

응답 (200):

json
{
  "session_token": "ltgt_8f3a...c91",
  "expires_at": "2026-05-11T13:25:00Z"
}
  • 평문 토큰은 응답에 1회 노출. 서버는 SHA-256 hash 만 저장.
  • TTL: 발급 시점 +5분.
  • 같은 idempotency_key 재호출 시 같은 미사용 토큰 반환.

토큰 사용 (merge)

http
POST /api/v1/me/merge
Authorization: <requester 세션 쿠키 또는 PAK>
Content-Type: application/json

# Option A — cross-device OTP
{ "target_user_id": 42, "otp_code": "123456" }

# Option B — same-device session_token
{ "target_session_token": "ltgt_8f3a...c91" }

응답 (200):

json
{
  "ok": true,
  "identity_link_id": 1287,
  "primary_user_id": 17,
  "linked_user_id": 42,
  "merged_via": "session_token"
}

오류 코드

상태코드의미
422conflicting_credentialsotp_codetarget_session_token 동시 전송
422missing_credentials둘 다 비어있음
422self_merge_forbidden토큰 target user_id == requester user_id
401token_expired5분 TTL 초과
401token_consumed이미 사용된 토큰
401invalid_tokenhash 불일치 또는 미존재

보안 모델

항목동작
저장SHA-256 hash 만 merge_session_tokens.token_digest 에 저장
단일 사용atomic consumed_at set, 두 번째 시도는 token_consumed
TTL발급 +5분
Target binding토큰은 발급 세션의 user_id 에 묶임
Self-merge 차단requester == target 이면 422 self_merge_forbidden
Auditidentity_links.merged_via = "session_token"

OTP vs session_token

OTPsession_token
사용 시점cross-devicesame-device
PoP 매체verified 이메일 6자리target 세션 쿠키 + hash 토큰
TTL10분5분
재사용1회 후 폐기atomic single-use

PAK 로 발급 (서버-서버 / CI-CD)

요구사항

  • PAK 가 account:merge 스코프 보유.
  • 요청 본문에 via: "pak" 명시 (스코프만으로 자동 승격 안 됨).
  • issued_via = "pak" 가 레코드 + audit log 양쪽에 기록.

curl

bash
curl -X POST https://api.1pass.dev/api/v1/me/merge/session-token \
  -H "Authorization: Bearer logi_pak_xxxxxxxx_yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" \
  -H "Content-Type: application/json" \
  -d '{"via":"pak","idempotency_key":"ci-merge-2026-05-11-001"}'

오류

  • 스코프 없이 via=pak403 insufficient_scope ({"error":"insufficient_scope","required":"account:merge"}).
  • 알 수 없는 via 값 → 400 invalid_via.
  • account:merge PAK 분실 시 즉시 revoke.

Limitations

  • iframe / cross-origin: SameSite 정책으로 target 세션 쿠키 미전송 가능 → 같은 top-level origin 에서 발급/전달 또는 OTP 폴백.
  • cross-device 의도 명확 시 OTP 권장.

다음 단계

MIT License · Identity가 제품의 신뢰를 만듭니다.