Files
baron_qa_write/docs/sso_guides/rp-session-and-logout.md
T
root c87e0aa0c1
Deploy EG-BIM QA Gateway / deploy (push) Successful in 56s
fix: 맵핑 관련 오류 로그 셋팅
2026-10-30 12:38:25 +09:00

10 KiB

RP Session and Logout Guide

자동 로그인

UserFront에서 RP를 선택했을 때 자동 로그인을 지원하려면 RP의 시작 URL이 직접 OIDC Authorization Code 흐름을 시작해야 한다.

  • RP가 state, nonce, PKCE를 생성한다.
  • UserFront나 Baron Backend가 RP 대신 authorization URL의 보안 상태를 만들지 않는다.
  • RP 시작 URL은 open redirect가 아니어야 한다.
  • 이미 유효한 Baron session이 있으면 login UI를 생략할 수 있지만 callback 검증은 생략하지 않는다.

Session 소유권

Backend API에 전달하는 Kratos Session Token과 Hydra Access Token의 구분은 Wiki의 Backend 보호 API의 credential 구분을 참고해 주세요.

  • Kratos session: Baron 로그인 session
  • Hydra authorization, consent, token chain: RP별 OAuth/OIDC protocol 상태
  • RP local session: RP가 생성하고 삭제하는 서비스 session

한 계층의 종료를 다른 계층의 완료로 추측하지 않는다. logout은 지원 가능한 전파 방식과 사후 검증을 가진다.

Kratos session과 Hydra authorization은 일대일 관계가 아니다. 한 Kratos session에서 여러 RP authorization이 만들어질 수 있고, 같은 RP도 여러 authorization 처리와 token chain을 가질 수 있다. consent는 authorization 과정에서 scope와 claim 제공을 승인하는 단계이며 로그인 session을 뜻하지 않는다. Hydra의 consent_request_id는 개별 authorization 처리 건을 식별하는 provider 기술 키다.

특정 RP 연결 해제

DELETE /api/v1/user/rp/linked/{clientId}는 현재 사용자의 지정 RP 연결을 해제한다. 처리 단위는 특정 Kratos session이 아니라 subject + client_id에 속한 사용자 RP authorization 전체다.

  • 해당 RP의 Hydra access/refresh token chain을 모두 폐기한다.
  • interactive installed RP는 Baron Token Vault의 local token family와 opaque session authorization을 차단하고 저장된 refresh token revoke 전달을 outbox에 기록한다. 외부 revoke 전달 완료는 worker 상태로 별도 확인한다.
  • Back-Channel Logout URI가 있으면 subject-only logout token 전파를 시도한다. 현재 요청에는 sid를 넣지 않으므로 sid가 반드시 필요한 RP에는 전파할 수 없다.
  • M2M client_credentials는 사용자 연결이 아니므로 이 API의 대상이 아니다.
  • Kratos session 자체는 종료하지 않는다.

HTTP 200은 Baron local authorization fence와 Hydra의 사용자·RP token chain revoke 요청이 완료되었다는 뜻이다. 외부 refresh token revoke 전달, Back-Channel Logout 전파 성공, RP local session 종료 완료를 뜻하지 않는다.

Hydra revoke 뒤 local consent 삭제가 일시적으로 실패하면 같은 요청을 재시도해 정리를 완료할 수 있다. 이미 전체 정리가 끝난 뒤 같은 DELETE를 다시 보내면 현재는 연결 없음으로 404를 반환한다.

DELETE /api/v1/user/sessions/{sessionId}는 해당 source session에 결합된 설치형 인증·복구 자격증명·짧은 세션을 함께 폐기한다. 같은 계정의 다른 source session에 결합된 설치형 인증은 보존한다.

DELETE /api/v1/user/sessions는 서버가 검증한 현재 session을 제외한 대상 목록을 고정하고, 대상 source session의 설치형 인증을 차단한 뒤 Kratos session을 각각 종료한다. 같은 Idempotency-Key의 재시도는 최초 대상만 처리하므로 이후 생성한 session을 폐기하지 않는다. 설치형 Hydra token 폐기는 durable outbox로 전달한다. 이 bulk API는 일반 RP Back-Channel Logout을 전파하지 않는다.

Back-Channel Logout

Back-Channel Logout을 지원하는 RP는 등록한 HTTPS endpoint에서 Baron 요청을 받는다.

다른 RP 설정을 편집할 때 기존 로그아웃 설정을 보존하는 기준은 메타데이터 스키마 정책을 참고해 주세요.

Baron은 RP가 등록한 Back-Channel Logout URI 전체에 POST하고, application/x-www-form-urlencoded body의 logout_token=<jwt>를 전송한다. 현재 logout token은 sub를 포함하고 sid는 포함하지 않는다. RP는 /api/v1/auth/backchannel/jwks.json의 key로 token을 검증한다.

  1. JWT signature와 iss, aud, iat, jti를 검증한다.
  2. events에 http://schemas.openid.net/event/backchannel-logout가 있고 nonce가 없는지 확인한다.
  3. sid 또는 sub가 있는지 확인하고 local session을 찾는다.
  4. 같은 jti의 재전송이 중복 side effect를 만들지 않게 처리한다.
  5. token이나 session 원문을 로그에 남기지 않는다.
  6. 이미 종료된 session의 logout도 안전한 성공으로 처리한다.

whitelist 제거에 따른 직접 로그아웃

활성 whitelist에서 사용자를 제거하면 Baron은 RP의 다음 중앙 검증 요청을 기다리지 않고 로그아웃을 전송합니다. 적용 범위와 최초 활성화의 비소급은 로그인 보안 정책을 따릅니다. 이 경로는 sub로 사용자의 RP 세션 전체를 대상으로 하므로 backchannel_logout_session_required=false가 필요합니다. URI 등록만으로 실제 세션 종료가 구현되는 것은 아닙니다.

RP 수신 endpoint는 다음 절차를 따릅니다.

  1. 서명과 iss, aud, iat, exp, jti, events를 검증합니다. 이 경로에서는 sub가 필수이며, 검증한 iss와 sub로 RP 사용자를 찾습니다.
  2. 이미 처리한 jti이면 세션 종료를 반복하지 않고 200 또는 204를 반환합니다.
  3. 새 사건이면 대상 사용자의 자체 세션과 관련 권한 캐시를 종료합니다.
  4. 세션 종료와 처리한 jti를 같은 transaction에 저장합니다. 별도 권한 캐시 정리가 실패하면 처리 완료를 기록하지 않고 재시도로 정리를 마쳐야 합니다.
  5. 종료를 완료한 뒤 200 또는 204를 반환합니다. 202는 완료 응답으로 처리되지 않습니다.

Baron은 같은 전송 사건에 같은 jti를 사용합니다. 재시도할 때는 유효한 iat와 exp로 다시 서명합니다. 현재 전송 작업에는 자동·수동 재시도의 최대 보관 기한이 없으므로 RP의 처리한 jti 기록을 자동 만료시키지 않습니다. 세션을 실제로 종료한 뒤 응답이 유실되어도 다음 요청에 안전하게 성공을 응답해야 합니다.

서명이나 claim 검증이 실패하면 400을 반환합니다. 세션 종료나 기록 저장이 실패하면 성공 응답을 반환하지 않습니다. Baron은 통신 오류와 200·204 이외의 응답을 미완료로 기록하고 간격을 늘려 재시도합니다. 설정 오류도 성공으로 처리하지 않으므로 운영자가 전달 결과의 원인을 확인하고 수정해야 합니다.

로그아웃 뒤에 오래된 로그인 callback이 도착하는 경우도 처리해야 합니다. 한 구현 방법은 RP 전체의 영속 종료 순번을 서버의 로그인 transaction에 시작 시 기록하는 것입니다. logout 수신 시 순번을 원자적으로 증가시키고 대상 subject의 마지막 종료 순번과 세션 삭제를 함께 저장합니다. callback에서 검증한 subject의 종료 순번이 로그인 시작 순번보다 크면 해당 로그인을 거부합니다. 순번 비교와 세션 생성은 logout 처리와 같은 subject 잠금으로 직렬화합니다. 만료되었거나 이미 완료한 로그인 transaction은 재사용하지 않습니다.

여러 RP 인스턴스는 같은 세션·중복 처리·종료 순번 원장을 사용해야 합니다. subject의 종료 순번 기록은 관련 미완료 로그인 transaction이 만료될 때까지 보관하며, jti 중복 처리 기록과 구분합니다. 새 로그인에는 새 state·nonce·PKCE를 사용합니다. 다만 삭제 뒤 재추가한 사용자는 새 로그인 후에도 늦게 도착한 통지로 다시 로그아웃될 수 있습니다.

명단 저장 성공은 RP의 로그아웃 완료를 뜻하지 않습니다. DevFront의 로그아웃 전달 결과에서 실패 원인과 재시도를 확인합니다. 통신 장애 중에는 기존 접근이 남을 수 있으며, 허용 시간을 제한하려면 RP 자체 세션에 절대 만료를 설정합니다. 사용 중 자동 연장만 있는 세션은 이 상한을 제공하지 않습니다. 별도 API가 자체적으로 허용하는 bearer token은 해당 API의 검증·폐기 정책으로 다뤄야 합니다.

실제 Docker 검증과 구현 기록은 #2481에 있습니다. 명단 추가·재추가가 추가 로그아웃을 만들지 않는지, 실패 후 재시도와 중복 수신이 안전한지, 다른 사용자의 세션이 유지되는지 확인합니다.

Back-Channel을 사용할 수 없는 경우

  • token refresh가 거부되면 local authorization을 종료한다.
  • 주기적 또는 중요 action 전 /user/me 같은 검증 endpoint로 Baron session 상태를 확인한다.
  • offline 상태와 명시적 logout을 같은 오류로 처리하지 않는다.
  • public client는 client secret을 포함하지 않는다.

UserFront와 원격 요청

  • UserFront는 Kratos session 상태를 기준으로 logout을 반영한다.
  • SMS 또는 NAVER WORKS logout link는 사용자 확인 뒤 Backend가 처리한다.
  • RP 유형에 따라 token revoke와 Back-Channel 전달 순서가 달라도 local session 제거의 최종 결과는 같아야 한다.

검증 항목

  • 동일 요청 재전송
  • 만료·잘못된 서명·다른 audience 거부
  • 이미 삭제된 session
  • RP endpoint timeout과 retry
  • refresh revoke 뒤 local session 종료
  • 로그와 audit의 민감정보 마스킹

인증 흐름의 정책 정본은 Authentication and Login Flow다.