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

61 KiB

RP 통합 가이드

이 문서는 RP 개발자가 서비스 목적 → RP 유형 → 필요한 옵션 → RP 구현 → Baron 설정 → 동작 확인 순서로 연동을 준비하는 가이드입니다. 먼저 아래에서 유형과 옵션 조합을 고르고, 이어지는 화면별 절차를 수행해 주세요. 지원 범위는 현재 저장소 코드 기준이며 운영 배포 여부와는 별도입니다.

조직·사용자 선택기를 RP 화면에 넣으려면 외부 서비스 조직선택기 통합 가이드를 참고하세요.

1. 목적에 따라 RP 유형 선택

flowchart TD
    A["어떤 주체가 서비스를 사용하나요?"] --> B{"사용자가 로그인하나요?"}
    B -->|아니요| M["Central M2M: 중앙 서버의 무인 작업"]
    B -->|예| C{"설치별 키와 Baron Token Vault로<br/>장비를 관리해야 하나요?"}
    C -->|예| I["Installed Interactive"]
    C -->|아니요| D{"RP Backend를 운영하나요?"}
    D -->|아니요| P["Browser/Mobile PKCE"]
    D -->|예| E{"로그인·동의 UI를 RP가 제어해야 하나요?"}
    E -->|아니요| W["Server-side Web: 중앙 UserFront 사용"]
    E -->|예| H["Server-side Headless: 자체 UI 또는 Baron JS UI"]
    W --> O["2절에서 필요한 옵션과 지원 조합 확인"]
    H --> O
    P --> O
    I --> O
    M --> O

설치 앱이라는 이유만으로 Installed Interactive를 선택하지는 않습니다. 장비별 키·등록/폐기·중앙 token 보관이 필요하면 Installed, 앱이 직접 token을 관리하는 일반 로그인이라면 Browser/Mobile PKCE를 검토합니다. 무인 프로그램도 사용자 PC에 비밀키를 배포하는 구조라면 중앙 workload용 M2M과 같은 것으로 취급하지 마세요.

만들려는 서비스 선택할 유형·등록 preset Baron에서 설정할 내용 RP 측에서 개발·지원할 내용 완료 확인
중앙 로그인 화면을 이용하는 사내 웹·포털·업무 서비스 Server-side Web · interactive_web_server Interactive, 기본 인증 client_secret_basic, callback URI, scope Backend의 로그인 시작·callback, state/nonce/PKCE 검증, code 교환·token 검증, 서버 token 보관, RP local session 생성·종료, secret 교체 정상·거절 callback을 처리하고 다른 state를 거부하며 서버 session으로 서비스를 이용할 수 있습니다.
자체 화면으로 로그인·동의를 제공하는 웹 서비스 Server-side Headless · interactive_web_headless Interactive, Headless 활성, private_key_jwt, HTTPS JWKS, callback·scope Web 공통 구현 + 서버 private key 보관·assertion 서명·키 교체, 로그인 transaction과 cookie 문맥 유지, same-origin adapter·CSRF 방어, 자체 UI 또는 Baron Consent JS UI 연결 로그인→동의→callback 전체가 같은 transaction에 연결되고 잘못된 assertion·다른 transaction 요청은 거부됩니다.
Backend 없이 브라우저·모바일 앱에서 일반 OIDC 로그인 Browser/Mobile PKCE · interactive_web_pkce Interactive, Public PKCE, 인증 none, callback·scope 앱의 state/nonce·PKCE S256 생성·검증, code 교환·token 검증, 실행 환경에 맞는 token 저장·폐기, 로그인 재시작 secret 없이 정상 로그인하고 다른 verifier·state를 거부합니다. 앱이 token 보관 책임을 집니다.
Desktop·CLI·local agent를 설치별로 등록하고 폐기하며 token을 중앙에 보관 Installed Interactive · interactive_installed_broker Interactive, Public PKCE, device_bound_singleflight, 사용자별 등록 device-key·활성 Token Vault 한도 Installation ID·device key 생성과 OS secure storage, PKCE 완료를 Broker에 제출, Device Proof 서명, opaque session 사용, operation 상태 조회·멱등 재시도, disable/rotate/revoke 처리 앱이 Hydra access/refresh token을 받지 않으며, 폐기된 장비의 기존 proof·session은 실패합니다.
사용자 로그인 없는 중앙 배치·서버 간 API 호출 Central M2M · central_service_m2m M2M, 중앙 workload, private_key_jwt, HTTPS JWKS, 필요한 scope 중앙 private key 보관·assertion 서명, client_credentials token 획득·만료 후 재획득, API 호출 권한 확인·키 교체 사용자 로그인·consent 없이 허용된 scope로만 호출하고 잘못된 키·만료 assertion은 거부됩니다.

기본 등록값은 RP 생성 preset을 따릅니다. Interactive와 M2M은 별도 Client로 등록하며 유형 변경이 필요하면 새 client_id를 만듭니다. Installed의 device public JWK는 Headless·M2M의 Client JWKS와 용도가 다릅니다.

2. 원하는 옵션과 RP 구현 연결

유형별 조합을 먼저 확인

아래의 가능은 설정만 하면 완료된다는 뜻이 아니라 해당 행의 RP 구현과 서버 선행조건을 충족한 뒤 사용할 수 있음을 뜻합니다. 현재 제한은 아래의 추가 로그인 보안 저장 경로에서 거부되는 조합입니다. 중앙 Tenant·계정 정책이나 별도의 장비 통제를 지원하지 않는다는 뜻은 아닙니다.

목적·옵션 Server-side Web Headless Browser/Mobile PKCE Installed Interactive Central M2M
중앙 화면으로 사용자 로그인 기본 자체 화면이 필요 없으면 Web 검토 기본 등록 로그인에 사용 해당 없음
로그인·동의 화면을 RP가 제어 Headless 선택 가능: UI·adapter 필요 이 가이드의 Headless 대상 아님 이 가이드의 Headless 대상 아님 해당 없음
Tenant 단독 제한 가능: OIDC 로그인 연동 가능: 기존 로그인 연동 가능: OIDC PKCE 연동 가능: 기존 등록 로그인 연동 사용자 로그인 옵션 대상 아님
whitelist 단독 사용 가능: logout 수신·세션 종료 필요 가능: logout 수신·세션 종료 필요 HTTPS 수신 서버와 실제 세션 종료 구현 필요 HTTPS 수신·세션 종료와 기존 Broker 계약을 함께 확인 사용자 로그인 옵션 대상 아님
AAL2 강제·Fresh TOTP 가능: 중앙 검증·logout 구현 필요 가능: 서명 introspection·logout 구현 필요 현재 제한 현재 제한 사용자 로그인 옵션 대상 아님
AAL2 권장만 설정 가능 가능 가능 가능 사용자 로그인 옵션 대상 아님
사용자 로그인 유지·갱신 RP Backend가 refresh 처리 RP Backend가 refresh 처리 앱이 refresh 처리 Baron Vault·Broker 사용 만료 후 client credentials로 재획득
설치별 장비 등록·키 회전·폐기 해당 없음 해당 없음 필요하면 Installed 검토 전용 기능 사용자 장비 기능 대상 아님

whitelist만 사용하면 중앙 token 검증과 introspection용 Client 인증 방식은 필수 조건이 아닙니다. token_endpoint_auth_method=none인 RP도 유효한 HTTPS Back-Channel Logout URI와 subject 전체 세션 종료를 지원하면 사용할 수 있습니다. 브라우저나 모바일 앱만 있고 서버 수신 endpoint가 없는 구성은 이 조건을 충족하지 않습니다. backchannel_logout_session_required는 false로 설정합니다.

AAL2 강제·Fresh TOTP의 기존 조건은 유지합니다. 이 옵션은 client_secret_basic/post 또는 실제 등록 인증 방식이 private_key_jwt인 활성 Headless RP에서 사용할 수 있습니다. Headless metadata만 private_key_jwt이고 실제 Hydra 등록이 none인 구성은 이 조건을 충족하지 않습니다. 해당 Headless RP는 등록된 HTTPS JWKS를 이용한 서명 introspection과 Back-Channel Logout을 구현해야 합니다. 기존 token·RP 자체 세션의 종료 범위는 Authentication and Login Flow를 따릅니다.

옵션별 구현·설정·확인표

하고 싶은 일 RP에서 먼저 구현·지원할 내용 Baron 설정 순서 확인할 결과
특정 회사·테넌트 사용자만 로그인 OIDC 로그인 성공·거절을 처리합니다. RP 내부 데이터 권한은 별도로 검사합니다. 로그인 보안에서 Tenant 트리 선택 → Tenant 제한 저장 대상 소속은 허용되고 범위 밖 계정은 거절됩니다. 선택 후보에 보인다는 이유만으로 그 계정에 로그인 자격이 생기지 않습니다.
허용 Tenant 안에서도 지정 인원만 로그인 Back-Channel Logout을 실제 세션 종료에 연결합니다. whitelist 거절 시 RP session을 만들지 않습니다. Tenant 정책 먼저 저장 → HTTPS logout URI 등록·subject 전체 종료 지원 확인 → 명단 구성 → whitelist 활성화. private 원본 가져오기는 정책 저장 후 실행 명단 밖 일반 계정은 로그인할 수 없습니다. 제거 후에는 별도로 로그아웃 전달 결과를 확인합니다.
로그인에 AAL2를 강제 추가 인증 완료 전 RP session을 만들지 않고 callback 오류·새 로그인 시작을 처리합니다. TOTP secret·내부 evidence를 RP에 복제하지 않습니다. RP AAL 정책 모드 = AAL2 강제, RP 요구 AAL = AAL2 → 공통 지원 항목 확인 → 저장 추가 인증 완료 전 서비스에 진입하지 못하고 완료 후 로그인됩니다.
AAL2를 권장하되 RP가 강제하지 않음 권장과 강제의 결과를 구분하고 중앙 로그인 흐름을 완료합니다. AAL2 권장, 요구 AAL2 → 저장 RP 권장을 강제 차단으로 바꾸지 않습니다. 중앙의 다른 필수 인증 요구는 계속 적용됩니다.
민감 기능에 최근 TOTP 확인 요구 중앙이 반환한 재인증 요구를 처리하고 검증 미완료 시 보호 기능을 실행하지 않습니다. RP 내부 중요 command의 인가도 별도로 구현합니다. 지원 조합 확인 → 민감 기능에 Fresh TOTP 요구 → 공통 지원 항목 확인 → 저장 일반 AAL2만 충족한 상태와 최근 TOTP를 확인한 상태를 구분합니다. 이 설정이 RP의 모든 내부 API를 자동 보호하지는 않습니다.
로그인 유지·refresh token 사용 Web·Headless는 서버, PKCE는 앱에서 갱신과 갱신 거절 처리를 구현합니다. Installed는 Broker operation과 Vault 계약을 사용합니다. 허용 scope에 offline_access → 실제 요청 scope·consent·refresh_token grant 확인 정상 갱신되고 폐기·거절 시 기존 local authorization을 계속 사용하지 않습니다. M2M에는 이 사용자 갱신 절차를 적용하지 않습니다.
서비스에 필요한 사용자 값 전달 필요한 claim만 소비하고 자료형·누락값을 처리합니다. claim을 RP 내부 권한 원장으로 대신 사용하지 않습니다. 설정에서 Scope·claim 정의 저장 → 필요 시 Consents & Claims에서 사용자값 별도 저장 → 실제 scope 요청 승인 범위에 맞는 claim만 최종 결과에 포함됩니다.
UserFront에서 앱을 눌러 바로 로그인 시작 RP 시작 URL에서 새 state·nonce·PKCE를 생성하여 authorization을 시작합니다. 설정 > 자동 로그인 활성 → RP 시작 URL 저장 기존 중앙 session이 있어도 callback 검증을 거쳐 RP session이 만들어집니다.
중앙 연결 해제 시 RP에서도 로그아웃 아래 logout 수신 계약과 local session 종료를 구현합니다. Back-Channel Logout URI 등록 → SID 필요 여부와 subject-only 전파 호환 확인 서명 검증 후 해당 사용자의 local session을 끝내고 중복 요청도 안전하게 처리합니다.
장비 수 제한·분실 장비 차단 Installed의 key/session 생명주기와 operation 거부 처리를 구현합니다. Installed 선택 → 등록 device-key·활성 Vault 한도 설정 → inventory에서 관리 한도 초과·disable·revoke 후 기대한 등록·operation 차단이 적용됩니다.

추가 로그인 보안을 위한 RP 공통 구현 계약

이 표는 whitelist·AAL2 강제·Fresh TOTP를 사용하는 RP의 구현 항목입니다. 중앙 token 검증은 whitelist 단독 사용에서 선택 사항이며, 나머지 두 옵션의 기존 요건은 유지합니다. Tenant 단독 제한의 설정은 Tenant 선택과 정책 저장을 따릅니다.

RP 구현 항목 구현 내용 완료 확인
중앙 token 검증 사용하는 경우 Baron의 /oauth2/introspect 결과를 접근 판단에 반영합니다. JWT 서명·만료 확인만으로 중앙 정책 변경을 감지했다고 간주하지 않습니다. 검증 장애를 허용으로 처리하지 않습니다. whitelist 단독 사용에서 이 기능을 생략하면 로그아웃 통지 처리 전 접근이 남을 수 있습니다.
Logout 수신 endpoint HTTPS POST에서 form의 logout_token을 수신합니다. /api/v1/auth/backchannel/jwks.json으로 signature, issuer, audience, 시간·events·jti 등을 검증하고 RP local session을 종료합니다. 잘못된 서명·audience를 거부하고 같은 jti 재전송과 이미 종료된 session을 안전하게 처리합니다.
Session 연결 Baron subject와 RP local session의 관계를 보관합니다. 현재 subject-only logout에는 sid가 없으므로 sub로 대상 session을 찾는 경로가 필요합니다. 중앙 연결 해제 성공과 RP local session 종료를 각각 확인합니다.
오류·재인증 로그인·검증·갱신 거절 시 local authorization을 중단하고 상황에 맞게 새 로그인 또는 문의를 안내합니다. 실패 응답을 성공으로 바꾸지 않고, 새 로그인에는 새 state·nonce·PKCE를 사용합니다.

정확한 introspection 요청·인증 계약은 OpenAPI의 /oauth2/introspect, logout 구현은 RP Session and Logout, Headless adapter는 Headless 가이드, 장비 구현은 Installed 가이드를 따릅니다.

3. 선택한 조합을 구현하고 설정하는 순서

flowchart TD
    A["서비스 목적과 필요한 옵션 목록 작성"] --> B["유형 선택표와 옵션 조합표 대조"]
    B --> C{"현재 지원 조합인가요?"}
    C -->|아니요| X["목적에 맞는 지원 유형으로 재설계하거나<br/>조합 지원 개발을 별도로 검토"]
    C -->|예| D["기본 Client 등록<br/>client_id·callback·scope·키 설정"]
    D --> E["유형별 RP 로그인 또는 M2M 기본 흐름 구현"]
    E --> F["선택 옵션의 RP 선행 구현<br/>검증·logout·adapter·device proof 등"]
    F --> G["RP endpoint·키 배치 후 Baron 설정 저장"]
    G --> J{"지원되는 추가 로그인 보안 옵션을<br/>사용하나요?"}
    J -->|예| H["선택한 옵션만 저장<br/>whitelist는 Tenant 저장·명단 구성이 선행"]
    J -->|아니요| I
    H --> I["정상·거절·재인증·로그아웃 확인<br/>설정 새로고침으로 저장값 확인"]

M2M과 추가 로그인 보안을 사용하지 않는 RP는 옵션 저장 단계를 건너뜁니다. AAL2 권장만 선택했다면 Tenant·명단을 만들 필요가 없습니다. 기본 Client 등록은 구현에 필요한 식별자를 확보하는 단계이며, 옵션 활성화는 RP 선행 구현을 완료한 다음에 진행합니다.

예를 들어 한맥가족 계열사 중 지정 인원만 이용하는 업무 웹은 기본 OIDC 로그인과 logout 수신을 먼저 구현합니다. Tenant 트리를 저장하고 명단을 구성한 뒤 whitelist를 활성화합니다. whitelist만 사용하면 중앙 검증 지원 체크는 필수가 아닙니다. 자체 로그인 화면이 필요한 Headless도 같은 logout 수신 계약을 구현합니다. 분실 장비의 접근을 끊는 Installed의 Device Key·Broker operation·inventory 계약은 별도로 확인합니다.

DevFront 등록

  1. RP 유형과 실행 위치를 먼저 선택한다.
  2. redirect URI를 exact value로 등록한다.
  3. Server-side Web은 client authentication과 인증정보를 확인한다. Headless·M2M의 private_key_jwt에는 HTTPS JWKS URI를 설정한다.
  4. PKCE client이면 public client 경계와 허용 method를 확인한다.
  5. scope, consent 설명, 소유 Tenant, 접근 relation을 설정한다.
  6. 저장 후 공개 metadata와 실제 authorization request를 대조한다.

연동 앱 목록 탐색

DevFront의 연동 앱 목록에서 이름 또는 ID를 입력하여 앱을 검색합니다. 검색창 옆의 고급 필터에서 유형과 상태를 선택합니다.

상단 제목에서 전체 검색·필터 결과 수를 확인합니다. 앱 이름은 일부 입력이나 오타로 검색할 수 있으며 ID는 전체 값을 입력합니다. 활성 사용자 수로 정렬하려면 검색어를 지우고 활성 사용자 열 제목을 누릅니다. 같은 열 제목을 다시 누르면 정렬 방향이 바뀝니다. 검색어를 입력하면 관련도 순서로 표시하고, 지우면 검색 전 정렬로 돌아갑니다. 수치의 의미와 표시 권한은 UI Design Policy를 따릅니다.

표가 화면의 가용 폭에 들어가면 페이지를 스크롤하고, 표 헤더는 앱 헤더 아래에 유지됩니다. 표가 가용 폭을 넘으면 표 영역 안에서 가로로 스크롤합니다. 이때 목록이 길면 같은 영역 안에서 세로로 스크롤합니다. 관계, 기기, 감사와 같은 긴 표의 탐색 방법은 긴 목록 탐색을 참고해 주세요.

등록 후 추가 설정 확인

RP를 만든 뒤 상세 화면에서 다음 항목을 확인해 주세요. RP 유형과 현재 계정의 권한에 따라 표시되는 항목이 다릅니다.

화면·항목 설정 및 확인할 내용
연동 설정 발급된 client_id, discovery·authorization·token endpoint와 RP 유형별 연동 예제를 확인합니다. 생성 후 로그인 callback의 Redirect URI도 이 화면에서 수정합니다. 유형을 변경해야 하면 새 Client로 등록합니다.
설정: 기본 정보 이름·설명·로고 등 사용자에게 표시될 정보와 소유 Tenant를 확인합니다. 소유 Tenant 지정만으로 로그인 대상이나 운영 권한이 자동 설정된다고 간주하지 않습니다.
설정: URI Back-Channel Logout URI와 SID Claim Required 설정을 확인합니다. 이 URI는 브라우저 이동 주소가 아니라 RP 서버의 logout token 수신 endpoint입니다. 현재 subject-only logout 전파와 SID 지원 범위는 로그아웃 가이드를 확인합니다.
설정: 보안 RP 유형에 맞는 Client 인증 방식, PKCE, secret 또는 HTTPS JWKS를 확인합니다. Public PKCE Client에 secret을 넣거나, Headless·M2M의 인증 방식을 로그인 보안 저장을 통과시키기 위해 임의 변경하지 않습니다.
설정: Scope·Claims 요청할 scope와 전달할 claim의 이름·값·자료형·대상 및 조건을 확인합니다. 동의가 필요한 정보는 실제 consent 화면과 token 결과까지 대조합니다.
Consents & Claims 동의 요청 항목과 claim 할당을 확인합니다. 로그인 whitelist 등록과 개인정보 제공 동의는 별도 작업입니다.
설정: 자동 로그인 사용할 경우 활성화하고 RP의 로그인 시작 URL을 지정합니다. 이 URL에서 RP가 state, nonce, PKCE를 생성하여 새 authorization 흐름을 시작해야 합니다.
설정: 테넌트 접근 제한 기존 metadata 기반 제한입니다. 아래 로그인 보안 > Tenant 제한과 저장 위치가 다르며 자동 동기화되지 않습니다. 기존 제한이 남아 있으면 함께 확인합니다.
로그인 보안 허용 Tenant, whitelist, AAL 모드·수준, Fresh TOTP, 중앙 검증·로그아웃 지원을 아래 순서로 설정합니다.
관계 조회·설정 편집·whitelist 관리 등 실제 작업에 필요한 RP 관계를 부여합니다. 화면 표시와 서버의 권한 검사를 각각 확인합니다.
Device inventory 설치형 RP에서 권한이 있는 경우 등록 장비와 상태를 확인합니다. 장비 등록·폐기 및 M2M 구성은 유형별 절차를 따릅니다.

설정 화면의 저장, 로그인 보안의 정책 저장, whitelist 멤버 추가·제거는 별도 요청입니다. 한 화면의 저장 성공으로 다른 설정까지 반영되었다고 판단하지 마세요. 기존 metadata 제한과 새 로그인 보안 제한이 모두 설정되어 있으면 로그인 시 두 조건을 각각 충족해야 합니다. 정확한 판정 구현은 RP 접근 검사를 참고해 주세요.

유형별 후속 설정

  • Refresh token: offline_access를 허용 scope에 등록하는 것만으로 발급되지 않습니다. 실제 authorization 요청의 scope, consent 승인, refresh_token grant 설정을 함께 확인합니다.
  • Custom Claims: 설정에서 claim 정의를 저장한 뒤 Consents & Claims에서 필요한 사용자별 claim 값을 별도로 설정·저장합니다. 최종 token에 의도한 값만 전달되는지 확인합니다.
  • Secret 관리: 연동 설정의 secret 재발급은 기존 secret을 즉시 무효화합니다. RP의 인증정보 교체 준비 후 수행하고 새 secret을 안전하게 보관합니다.
  • Headless: HTTPS JWKS와 키를 구성한 뒤 화면의 JWKS 캐시 상태를 확인합니다. 키 변경 시 Refresh로 갱신하거나 필요한 경우 Revoke Cache를 사용하고 실제 client assertion을 검증합니다. 세부 절차는 Headless RP Consent를 참고합니다.
  • Installed Interactive: 등록 device-key 수와 활성 Token Vault 수의 한도를 확인하고 Device inventory에서 장비 상태를 관리합니다. Device Proof·등록·폐기 절차는 설치형 RP 가이드를 따릅니다.
  • Central M2M: 중앙 workload에서 private_key_jwt와 HTTPS JWKS를 사용합니다. 사용자 consent나 설치형 사용자 장비 흐름과 혼합하지 않으며, 화면에 노출되지 않는 machine 설정을 임의 입력하는 절차로 대체하지 않습니다.

날짜·시간 Custom Claim 편집

날짜·시간 Claim을 변경하지 않으면 다른 설정을 저장해도 원본 값과 날짜 설정을 보존합니다. 기본값은 RP의 설정에서, 사용자별 값은 Consents & Claims의 Claim 편집 화면에서 변경해 주세요. 값을 입력하기 전에 해당 Claim의 시간대 선택 값을 확인해 주세요. 잘못된 날짜와 일광 절약 시간 전환으로 존재하지 않는 현지 시각은 저장할 수 없습니다. 같은 현지 시각이 두 번 나타나면 입력란 아래의 발생 순서 선택에서 첫 번째 발생 또는 두 번째 발생을 선택해 주세요.

저장 단위와 날짜 경계는 Date and Time Standard의 RP custom claim 예외를 따릅니다. 저장 후 같은 편집 화면을 다시 열어 입력한 날짜·시각과 선택한 시간대가 유지되는지 확인해 주세요.

NAVER WORKS 사용자 식별자 사용

NAVER WORKS 사용자 식별자가 필요하면 authorization 요청에 profile을 포함하세요. 이 필드에 별도 Custom Claims 정의를 등록하지 마세요. 동의 후 ID Token 또는 UserInfo에서 naverworks_user_id를 읽으세요. 필드가 없으면 NAVER WORKS 식별자 연결을 생략하세요.

현재 소속 판정은 Kratos traits를 사용합니다. metadata_admin에만 있는 추가 소속은 #2219에서 추적합니다.

제공 조건은 메타데이터 스키마 정책을 따릅니다. 구현은 RP claim 구성을 참고하세요.

RP 로그인 보안

  • 보안설정은 접근 대상, 인증 요구사항, RP 연동 지원 확인으로 구분합니다. 기능 사용은 토글, RP 지원 여부 확인은 체크박스, AAL 모드·수준은 선택 상자로 편집하며 정책 저장 후 적용됩니다.
  • 허용 테넌트는 이름 라벨로 표시합니다. 허용 Tenant 추가로 선택하고 라벨의 × 버튼으로 하나씩 제거한 뒤 정책 저장을 누릅니다. 라벨에 포인터를 올리면 ID를 확인할 수 있으며, 현재 후보 목록에 없는 기존 선택도 ID와 함께 보존됩니다. 허용 테넌트가 없으면 화이트리스트를 켠 상태로 저장할 수 없습니다. 테넌트 선택을 비우고 저장하면 테넌트 제한이 해제됩니다.
  • DevFront의 Client 로그인 보안 화면에서 허용 Tenant, 사용자 whitelist, Required AAL, Fresh TOTP 요구를 관리한다. whitelist는 허용 Tenant가 없으면 활성화할 수 없다.
  • RP config_editor는 로그인 보안 정책을 조회·수정할 수 있고, RP manage 권한은 정책과 whitelist 멤버를 함께 관리한다. 장비·비밀·감사 전용 조회 권한에는 whitelist가 노출되지 않는다.
  • whitelist는 별도 Tenant나 AdminFront 조직 기능이 아니라 RP가 참조하는 identity member list다. Exact Super Admin은 whitelist 제한의 예외지만 AAL·Fresh TOTP·계정 정상화 요구의 예외는 아니다.
  • Tenant 단독 제한과 whitelist·AAL2 강제·Fresh TOTP의 지원 조건은 로그인 정책과 위 유형별 조합표를 따릅니다.
  • whitelist 최초 활성화의 비소급과 이후 명시적 제거의 종료 범위는 위 로그인 정책을 따릅니다. 명단 추가는 기존 사용자를 로그아웃시키지 않습니다. 제거 후에는 로그아웃 전달 결과에서 RP의 처리 응답을 확인합니다.
  • RP에는 Factor 종류나 내부 evidence를 claim으로 전달하지 않는다. 인증 성공 또는 표준 오류 결과만 소비한다.

유형을 변경해야 하면 기존 Client를 다른 유형으로 변환하지 않고 새 client_id로 등록한다.

whitelist·AAL2 강제·Fresh TOTP 활성화 전에 준비할 사항

  1. RP에서 Back-Channel Logout을 실제 세션 종료에 연결합니다. 서명 검증·중복 처리·로그인 완료 경합은 RP Session and Logout을 따릅니다.
  2. 기본정보에서 유효한 HTTPS Back-Channel Logout URI를 등록합니다. whitelist를 사용할 때는 backchannel_logout_session_required=false로 설정합니다. 지원 체크박스만 선택해도 URI가 등록되는 것은 아닙니다.
  3. whitelist만 사용하면 중앙 token 검증은 필요에 따라 선택합니다. AAL2 강제·Fresh TOTP도 사용하면 중앙 검증을 구현하고 기존 Client 인증 방식·Headless JWKS 조건을 충족해야 합니다.

Tenant 단독 제한은 위 준비 절차 없이 Tenant 선택과 정책 저장으로 진행합니다. AAL2 권장도 whitelist·AAL2 강제·Fresh TOTP를 함께 켜지 않으면 위 조건을 요구하지 않습니다. 현재 검사는 RP 정책 유효성 검사와 등록 capability 검사를 기준으로 합니다.

Headless introspection 요청 구현

  1. RP Backend에서 등록된 HTTPS JWKS의 공개키와 짝이 되는 private key로 assertion을 서명합니다. 실제 Client 등록 인증 방식과 Headless 설정 모두 private_key_jwt여야 합니다.
  2. iss와 sub에는 client_id, aud에는 Baron의 HYDRA_PUBLIC_URL에 /oauth2/introspect를 붙인 전체 공개 URL을 넣습니다. 로그인 endpoint URL·상대경로·여러 audience를 넣지 않습니다.
  3. iat는 현재 Unix 초, exp는 그보다 뒤이며 최대 300초 이내, jti는 매 요청마다 새로 생성한 고유값으로 지정합니다. nbf를 넣으면 현재보다 미래가 아니어야 합니다. 일반적으로 짧은 수명을 사용하고 RP 서버의 시간을 동기화해 주세요.
  4. 다음 form을 POST합니다. Basic Authorization이나 client_secret을 함께 보내지 않습니다. 예시의 token·JWT는 RP Backend 내부에서만 취급합니다.
POST https://<hydra-public-origin>/oauth2/introspect
Content-Type: application/x-www-form-urlencoded

token=<url-encoded-token>
&client_id=<url-encoded-client-id>
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=<url-encoded-signed-jwt>
  1. 200에서도 active가 false면 해당 local authorization을 중단합니다. 401 invalid_client이면 등록 정보·서명·audience·시간·assertion 재사용 여부를 확인합니다. 503이면 처리 결과를 허용으로 해석하지 않습니다.
  2. timeout·503 이후 재시도도 새 jti로 새 assertion을 서명합니다. 인증에 성공한 assertion은 token 조회나 중앙 정책 검사에서 후속 오류가 발생해도 이미 소비되었을 수 있습니다. 다른 token 조회에도 같은 assertion을 재사용하지 않습니다. 같은 Client의 다른 요청에 같은 jti를 사용하지 마세요.

이 일회용 계약은 신규 introspection에만 적용됩니다. 기존 Headless 로그인·consent·poll은 기존 endpoint별 audience·challenge·session 결속 계약을 유지하며 일괄적으로 새 jti를 강제하지 않습니다. 현재 원격 Wiki의 기존 계약을 강화할지는 #2164에서 별도 검토합니다. 구현·검증 및 배포 상태는 #2163을 참고해 주세요.

Tenant 선택과 정책 저장

  1. 대상 RP의 로그인 보안 탭에서 허용 Tenant 추가를 누릅니다. 선택한 Tenant는 이름 라벨로 표시됩니다.
  2. AdminFront의 상위 Tenant 선택과 같은 트리에서 이름·슬러그로 검색하거나 펼치기 버튼으로 탐색합니다. super_admin에게는 활성 공개 후보의 root들이 접힌 상태로 나타나고, 검색하면 일치하는 항목의 경로가 펼쳐집니다.
  3. 일반 계정은 소속·관리 권한이 있는 활성 공개 후보를 선택합니다. 한맥가족 소속 계정에는 hanmac-family root와 직접 자식(1depth) 중 활성 공개 Tenant도 기본 후보로 표시됩니다. 2depth 이하가 이 규칙만으로 추가되지는 않으며 기존 소속·관리 후보는 유지됩니다. 비공개 가족 하위 소속도 가족 후보를 조회할 수 있지만 비공개 Tenant 자체는 선택 후보로 나오지 않습니다.
  4. 필요한 Tenant를 선택하고 여러 개면 다시 허용 Tenant 추가를 엽니다. 선택한 항목을 빼려면 해당 라벨의 × 버튼을 누릅니다. 후보에 더 이상 없는 기존 설정은 자동 삭제되지 않으므로 이름 대신 기존 선택 표시가 나오면 ID와 현재 상태를 확인해 주세요.
  5. Tenant 제한 저장을 누릅니다. 성공 토스트를 확인하고 새로고침해 선택값이 유지되는지 확인합니다. whitelist·AAL2 강제·Fresh TOTP도 필요하면 위의 해당 옵션 준비 절차를 별도로 진행합니다.

기본 후보 표시는 자동 선택·저장이 아닙니다. Tenant 선택은 RP 관리 권한이나 로그인 자격을 새로 부여하지 않습니다. 로그인 허가 판정에서는 비공개 소속만으로 상위 공개 회사 소속을 충족하지 않습니다. Tenant 제한을 비워도 기존 metadata 제한 등 다른 접근 조건이 함께 해제되지는 않습니다. 후보 API 계약은 OpenAPI의 GET /api/v1/dev/clients/{id}/login-access/tenants, 로그인 정책 정본은 Authentication and Login Flow를 참고해 주세요.

whitelist와 AAL 설정

  1. whitelist를 사용하려면 먼저 허용 Tenant를 선택하고 정책을 저장합니다.
  2. 화이트리스트 섹션의 스위치를 켜면 검색·사용자 테이블이 펼쳐집니다. 끄면 제목과 스위치만 남고 명단은 삭제되지 않습니다. 테이블 위 검색란은 등록된 명단을 입력 즉시 필터링합니다. 사용자 추가 모달에서 기존 조직도 사용자 다중선택기로 대상을 선택·확인하고 선택한 사용자 추가를 누릅니다. 중복·기등록 사용자는 제외하며 일부 추가 실패 시 실패 항목만 남겨 재시도할 수 있습니다. 비공개 Tenant 가져오기는 같은 모달의 비공개 테넌트에서 가져오기에서 변경한 정책을 저장한 뒤 사용합니다. 사용자 추가·제거는 각각 즉시 요청되며 정책 저장과 별개입니다. 대상은 활성 계정이며 RP의 실제 허용 소속 조건도 충족해야 합니다.
  3. 명단을 확인한 뒤 정책 저장을 눌러 화이트리스트 사용 여부를 적용합니다. 명단 추가만으로 whitelist가 활성화되지는 않습니다. 개별 추가·제거 결과는 갱신된 명단을 확인하고, 반응이 불명확하면 새로고침해 확인합니다.
  4. 추가 인증이 필요하면 RP AAL 정책 모드와 RP 요구 AAL을 함께 설정합니다. AAL2 강제는 모드 AAL2 강제와 수준 AAL2를 선택합니다. AAL2 권장은 강제와 다르며, 사용 안 함도 중앙 Tenant·계정의 다른 인증 요구를 없애지는 않습니다.
  5. 민감 기능에 최근 TOTP 확인이 필요하면 민감 기능에 Fresh TOTP 요구를 설정합니다. 일반 AAL2 충족만으로 Fresh TOTP 요구까지 충족했다고 판단하지 마세요.

사용자를 제거한 뒤에는 로그아웃 전달 결과에서 대상 사용자의 UUID, 상태와 시도 횟수를 확인합니다. 전달 대기와 실패는 RP 로그아웃 완료를 뜻하지 않습니다. 실패 원인을 해결하면 자동 재시도를 기다리거나 다시 전송을 누릅니다. 미완료 작업을 우선하여 최대 100건을 표시합니다. 전달 완료는 RP가 성공을 응답했다는 뜻이며, 실제 세션 종료는 RP 연동 테스트로 확인해야 합니다.

명단에는 UUID와 함께 조회 권한이 있는 사용자의 대표조직·이름·직급·이메일이 표시됩니다. RP 멤버 관리 권한만으로 개인정보 전체를 조회할 수는 없으며, 대표조직과 직급은 해당 대표 Tenant의 조회 범위 안에서 제공됩니다. 대표조직은 가져온 비공개 Tenant나 소속 Root를 뜻하지 않습니다. 정보 없음은 권한 제한·미등록·조회 실패를 포함할 수 있으며 저장 실패를 뜻하지 않습니다. 이 경우에도 UUID로 멤버를 확인하고 제거할 수 있습니다. 구현·반영 상태는 #2165를 참고해 주세요.

저장 결과와 오류 확인

화면 결과 다음 작업
저장 중 완료될 때까지 기다립니다. 중복 저장하지 않습니다.
저장 성공 성공 안내 후 새로고침하여 Tenant 제한·화이트리스트·AAL 설정이 유지되는지 확인합니다.
HTTP 401·403 세션과 해당 RP의 조회·정책 변경·멤버 관리 권한을 확인합니다. 이 권한들은 서로 다릅니다.
HTTP 400·422 활성 공개 Tenant와 whitelist의 Tenant 선행조건을 확인합니다. whitelist에는 HTTPS logout URI와 subject 전체 종료 지원이 필요합니다. AAL2 강제·Fresh TOTP를 함께 사용하면 중앙 검증 지원과 Client 인증 방식도 확인합니다.
HTTP 404·409 대상 RP와 현재 저장값을 확인합니다. 다른 변경이 있으면 최신 설정을 확인한 뒤 필요한 변경만 다시 저장합니다.
통신 오류·HTTP 5xx·결과 미확인 저장된 정책 다시 조회로 서버 값을 확인합니다. 실패 응답이나 무응답만으로 미저장이라고 단정하지 않습니다.

저장된 정책 다시 조회는 편집 중인 초안을 유지하고 조회 시점의 Tenant 제한·화이트리스트 저장값을 별도로 표시합니다. 초안과 저장값을 비교한 뒤 재시도 여부를 결정하세요. AAL 등 다른 항목도 편집을 마친 후 새로고침하여 확인합니다. 저장 성공 후 최신 조회만 실패한 경우에는 저장 실패와 구분해서 안내합니다.

비공개 Tenant에서 whitelist 가져오기

다음은 로컬 구현 기준의 작업 절차입니다. 운영 반영 여부는 #2153에서 확인합니다. 로그인 정책 정본은 Authentication and Login Flow, 가져오기 API의 권한·후보·오류 계약은 OpenAPI의 POST /api/v1/dev/clients/{id}/login-members/import를 따릅니다.

  1. 허용 Tenant 추가에서 트리를 검색하여 활성 공개 Tenant를 선택하고 먼저 정책 저장을 누릅니다. 기존 private 조건이 남아 있으면 실제 로그인 대상자의 공개 소속과 접근 범위를 확인해 교체합니다. 적절한 공개 후보가 없으면 제한을 임의 해제하지 말고 담당 관리자에게 소속과 설정 권한을 확인해 주세요. 로그인 허가 판정에서는 private 소속만으로 상위 회사 소속을 충족하지 않습니다.
  2. 비공개 Tenant에서 가져오기에 권한이 있는 원본 Tenant UUID를 입력하고 미리보기를 누릅니다. 일반 관리자는 RP의 manage_login_members와 원본 Tenant의 view·view_users가 모두 필요합니다. 기존 권한 상속과 정확한 super_admin 예외가 적용됩니다.
  3. 신규 후보의 identity ID와 기존 사용자 수를 확인하고 인원수가 표시된 N명 추가 버튼으로 적용합니다. 후보는 원본의 직접 구성원 중 활성 상태이며 RP의 비공개가 아닌 실제 허용 소속을 충족하는 사용자입니다. 후보가 없으면 추가 버튼은 비활성화됩니다.
  4. 반영된 명단을 확인합니다. 가져오기는 기존 명단을 유지하며 원본의 이후 변경을 자동 동기화하지 않습니다. 필요하면 whitelist를 별도로 활성화하고 로그인 보안 설정을 저장합니다.

미리보기와 적용 모두 권한을 다시 검사합니다. 403이면 RP·원본 권한을 확인하고, 409이면 변경된 소속·정책을 확인한 뒤 미리보기부터 다시 수행합니다. 가져오기 실패를 로그인 허용으로 해석하지 않습니다. 실제 서비스 검증 방법은 Contributor Guide를 참고합니다.

Authorization Code 흐름

  • RP가 state, nonce, PKCE verifier/challenge를 생성하고 callback까지 검증한다.
  • Baron은 login/consent challenge를 처리하지만 RP local session을 대신 소유하지 않는다.
  • redirect URI는 등록 값과 exact match여야 한다.
  • callback의 error도 state를 검증한 뒤 처리한다.
  • access/ID token claim을 권한 원장으로 사용하지 않고 필요한 command는 Backend authorization을 다시 거친다.

Consent API를 직접 사용하는 RP는 OpenAPI의 ConsentFailureResponse의 code로 실패 원인을 구분합니다. status는 실제 HTTP 상태와 같습니다. message는 선택적인 영문 설명이며 번역하지 않습니다. next_action은 다음 행동을 나타내며, request_id는 문의와 서버 로그를 연결합니다.

RP는 오류 상세에 HTTP 상태와 code를 표시합니다. message가 있으면 영문 그대로 표시하며, 문자열을 해석해서 오류 종류를 결정하지 않습니다. pkce_restart_required만으로 PKCE verifier 불일치를 단정하지 않습니다. 같은 challenge로 자동 재시도하지 않습니다.

restart_login이면 사용자 동작으로 새 authorization 요청을 시작한다. contact_support이면 인증 조건을 확인·해결한 뒤 새 로그인을 시작한다. 알 수 없는 행동에는 문의 안내를 제공한다. 새 흐름에서는 기존 state, nonce, PKCE verifier/challenge를 재사용하지 않는다.

브라우저 리다이렉트형 RP는 이 API JSON을 callback으로 자동 수신하지 않는다. 해당 오류는 UserFront가 원인·다음 행동·문의용 요청 ID로 표시한다. RP callback은 기존 OIDC 오류와 state 검증 계약을 유지하며 임의 redirect URL로 상세 오류를 전달하지 않는다.

Installed RP 시간 오류 처리

오류 계약과 영문 상세 정책은 Error Handling Policy에서 관리합니다. 구현 전환은 #2186에서 추적합니다.

설치형 RP의 authorization completion은 시간 오류에서 HTTP 400과 status=400을 반환합니다. code는 device_proof_expired처럼 서버가 확인한 실패를 식별합니다. 시간 진단에는 stage=installed_device_proof, next_action, retryable=false, request_id도 포함됩니다. 선택적인 message는 영문 그대로 표시합니다.

시간 진단은 만료, 아직 사용할 수 없는 시각, 허용 범위를 벗어난 미래·과거 발급 시각, 필수 시간 값·유효기간 규칙 위반을 구분합니다. 예를 들어 device_proof_issued_at_future는 발급 시각이 서버의 허용 미래 범위를 벗어났다는 뜻이며, 실제 기기 시계가 틀렸다고 확정하는 진단은 아닙니다. 정확한 원인 코드와 응답 필드는 OpenAPI의 InstalledDeviceProofTimeFailureResponse를 따릅니다. 일반 timeout이나 PKCE verifier 불일치로 치환하지 않습니다.

restart_login이면 기기·서버의 시간 동기화와 RP의 proof 생성 설정을 확인한 뒤 사용자 동작으로 새 로그인을 시작합니다. contact_support이면 요청 ID와 함께 관리자에게 문의합니다. 알 수 없거나 계약과 맞지 않는 진단은 일반 입력 오류로 처리하며, 같은 proof와 authorization code를 자동 재전송하지 않습니다. 상세 복구 절차는 설치형 RP 가이드의 Device Proof 시간 오류 처리를 참고합니다.

Headless 흐름

  • 자체 동의 화면을 구현하는 Consent API 절차와 Baron 제공 JS UI의 탑재 방법은 Headless RP Consent 가이드를 따른다. 독립 JS UI와 RP별 consent 진입 계약의 검증·배포 상태는 #2104에서 추적한다.
  • Headless RP는 Backend에서 private key를 보관하고 private_key_jwt를 사용한다.
  • JWKS는 HTTPS로 제공하고 현재 key와 rotation overlap을 관리한다.
  • phone/link login의 pendingRef와 polling 상태를 정상 상태로 처리한다.
  • redirect가 아직 없다는 이유만으로 pending을 실패로 바꾸지 않는다.
  • consent와 Tenant 제한은 일반 OIDC 흐름과 같은 원장 검사를 사용한다.

관계와 운영 권한

  • RP owner Tenant와 RP 접근 대상은 다른 relation이다.
  • 조회, 설정 편집, consent 관리, audit 조회, installed device 운영 권한을 분리한다.
  • 화면의 capability projection은 action 표시용이며 Backend가 mutation을 재검사한다.
  • 직접 부여와 Tenant 상속의 결과를 raw tuple 하나로 추측하지 않는다.

검증

  • authorization 시작과 callback state 검증
  • invalid redirect/JWKS/client assertion 거부
  • consent accept/reject와 선택 scope
  • logout과 token revoke
  • unauthorized Tenant/RP actor 거부
  • secret, code, token이 log에 남지 않는지 확인
  • 중앙 introspection과 refresh에서 policy revision, membership, credential, Tenant 요구 변경이 반영되는지 확인
  • whitelist 단독 사용에서 중앙 검증 없이 정책을 저장하고 명단 밖 신규 로그인을 거부하는지 확인
  • 명단 제거 후 직접 logout 수신·실패 재시도·기존 RP 세션 종료와 다른 사용자 비영향 확인

설치형 RP는 Installed RP Guide, session 종료는 RP Session and Logout, 정확한 API는 Backend OpenAPI를 따른다.

설치형 앱의 세션 복구와 다중 프로세스

DevFront의 RP 상세 → 설정 → 애플리케이션 프로필에서 설치형 앱을 선택한 뒤, Device quota 입력 칸과 같은 줄의 RP 복구 발급 스위치를 켜고 앱이 completion에 sessionRefreshSupported=true를 보내면 Baron 복구 자격증명을 발급합니다. RP별 기본값은 차단이며, 허용 여부를 운영자가 선택합니다. 서버 전체 기능의 기본값은 허용입니다. INSTALLED_SESSION_REFRESH_ENABLED=false는 긴급 전체 차단에만 사용하며, 기존 환경 파일에 명시된 false는 기본값 변경 후에도 차단으로 적용됩니다. Hydra access/refresh token은 계속 서버 Vault에만 보관합니다. 앱은 OAuth token endpoint 대신 OpenAPI의 installed sessions refresh/revoke API를 사용합니다.

기본 설정에서 짧은 세션은 15분이며 유효한 operation으로 연장됩니다. 복구 자격증명은 마지막 성공한 복구 후 7일 미사용 만료와 최초 PKCE 인증 후 30일 절대 만료를 함께 적용합니다. 짧은 세션의 활동만으로 복구 자격증명의 미사용 만료를 연장하지 않습니다. 복구 성공은 절대 만료를 연장하지 않습니다. 프로그램을 종료하고 다음 날 실행해도 두 기한 안이고 중앙에서 폐기되지 않았다면 로그인 화면 없이 복구할 수 있습니다. 실제 기한은 응답의 만료 필드로 판단하세요. 기한 초과나 명시적 폐기 뒤에는 PKCE 로그인이 필요합니다.

여러 프로세스는 같은 issuer·RP·OS 사용자·enrollment 저장소와 프로세스 간 잠금을 사용합니다. 잠금을 획득한 후 저장소를 다시 읽고, 이미 갱신된 세션이면 그대로 사용합니다. 갱신 담당 프로세스만 요청하고 새 자격증명·세션·generation을 OS 보안 저장소에 원자적으로 저장합니다. 서로 다른 사용자 계정의 자격증명은 공유하지 않습니다. 기기 private key와 복구 자격증명을 함께 보호해야 합니다.

  1. 네트워크 호출 전에 현재 자격증명과 logical Idempotency-Key, 시작 시각을 영속 저장합니다.
  2. 각 시도에서 새 jti로 proof를 서명합니다. 재시도에서도 자격증명과 Idempotency-Key는 그대로 둡니다.
  3. 응답 유실 시 60초 안에 같은 요청을 재시도합니다. 이미 완료된 요청은 같은 결과를 반환합니다. 새 자격증명에는 새 Idempotency-Key를 사용합니다.
  4. HTTP 409 refresh_in_flight는 잠시 후 같은 요청으로 재시도합니다. 503을 곧바로 로그인 실패로 처리하지 않습니다. 결과가 불확실하면 서버가 해당 인증을 차단할 수 있으며 이후 401에서는 새 로그인이 필요합니다.
  5. 정상 복구는 같은 인증에 속한 다른 프로세스의 아직 유효한 세션을 폐기하지 않습니다. 이전 자격증명을 다른 요청에 재사용하면 해당 인증 전체가 폐기됩니다.

로그아웃은 revoke API가 성공하기 전에 로컬 폐기 의도를 저장하고 세션 사용부터 중단합니다. 오프라인이면 폐기 요청을 다음 연결 때 재시도하며 이 상태에서 자동 복구하지 않습니다. 로컬 파일 삭제만으로 서버 인증을 폐기했다고 판단하지 마세요.

RP별 발급·갱신 허용은 위 설정 화면의 RP 복구 발급 스위치에서 변경합니다. 스위치 변경은 즉시 저장되며 Device quota 저장과 별개입니다. 복구 키 메뉴에서는 사용자 ID로 조회하여 특정 인증을 폐기할 수 있습니다. 복구 발급 스위치를 끄면 확인창이 표시되며, 복구 발급 끄기 확인을 선택하면 해당 RP의 기존 복구 키도 무효화합니다. 다시 켜도 이전 키는 되살아나지 않으므로 새 PKCE 로그인에서 새 키를 발급받아야 합니다. 아직 유효한 짧은 세션과 다른 RP의 설정·복구 키는 유지됩니다. 다른 관리자가 먼저 설정을 변경했다면 화면을 갱신한 뒤 다시 저장하세요. 조회에는 device inventory 권한, 설정 변경·폐기에는 device policy 관리 권한이 필요하며 super 관리자는 직권 폐기할 수 있습니다. 화면에는 자격증명 원문이 없습니다. 복구 키 목록의 사용자·디바이스를 확인한 뒤 행의 폐기를 선택하고 확인합니다. 이 개별 폐기는 해당 인증의 모든 세션에 적용되며 다른 사용자의 인증을 보존합니다. 외부 세션 종료와의 연결은 Session and Logout을 참고하세요.

운영 시 INSTALLED_SESSION_REFRESH_IDLE_TTL(기본 168h), INSTALLED_SESSION_REFRESH_ABSOLUTE_TTL(720h)로 기한을 설정합니다. 설정을 줄이면 기존 인증에도 더 짧은 기한을 적용하며 이후 늘려도 이전 기한을 되살리지 않습니다. 기능을 껐다 켜도 기존 복구 자격증명은 다시 유효해지지 않습니다. 이미 유효한 짧은 세션은 원래 기한까지 사용할 수 있습니다. 데이터베이스 복원 시 트래픽을 열기 전에 INSTALLED_SESSION_REFRESH_EPOCH를 이전에 사용하지 않은 값으로 바꾸세요. 모든 서버에 동일한 설정을 적용하고 순차 배포 중 서로 다른 정책이 경쟁하지 않게 하세요.

갱신과 폐기 endpoint는 Backend 인스턴스별 IP당 합산 분당 60회 제한을 적용합니다. 다중 인스턴스 전체 제한은 gateway에서 별도로 구성하세요. PostgreSQL 연결 풀은 refresh advisory lock과 내부 transaction이 동시에 사용할 연결 여유가 필요합니다. 자격증명, proof, 응답 본문을 로그에 남기지 마세요. 폐기 outbox 전달 상태와 409·503 비율을 운영 모니터링에 포함하세요.

갱신에 사용할 값과 최초 응답

갱신 요청의 sessionRefreshCredential에는 직전 성공한 completion 또는 refresh 응답의 sessionRefreshCredential 문자열 원문을 넣습니다. 앱이 임의로 생성하거나 hash로 바꿔 보내지 않습니다. 다음 값의 용도를 구분하세요.

값 RP에서 사용하는 곳
sessionRefreshCredential 복구·폐기 요청 JSON 본문. 성공할 때마다 최신 값으로 교체
deviceSessionHandle 일반 operation의 X-Baron-Device-Session 헤더
기기 private key X-Baron-Device-Proof JWT 서명. 키 원문은 전송하지 않음
Idempotency-Key RP가 새 갱신마다 생성하는 고유 요청 식별자. 동일 요청 재시도에는 재사용
refreshGeneration 응답의 자격증명 세대 번호. 인증 수단으로 전송하지 않음

최초 로그인은 POST /api/v1/rp/installed/authorizations/complete의 기존 PKCE·기기 등록 필드에 sessionRefreshSupported: true를 추가합니다. 해당 RP에서 복구 발급을 허용했고 서버 전체가 차단되지 않았다면 HTTP 200 JSON 본문에 복구 필드가 추가됩니다. 아래 문자열과 시각은 예시이며 실제 값으로 대체해야 합니다.

{
  "deviceId": "7bd0c106-608e-4d57-8d37-c95b2bc94613",
  "deviceSessionHandle": "<opaque-session-handle>",
  "sessionExpiresAt": "2026-09-21T09:15:00Z",
  "sessionRefreshCredential": "<opaque-recovery-credential>",
  "refreshIdleExpiresAt": "2026-09-28T09:00:00Z",
  "refreshAbsoluteExpiresAt": "2026-10-21T09:00:00Z",
  "refreshGeneration": 1
}

Hydra access_token·refresh_token은 응답에 없습니다. RP에서 복구 발급을 차단했거나 서버 전체가 차단된 경우, 또는 앱이 opt-in하지 않으면 복구 관련 네 필드가 생략됩니다. RP는 필드 존재 여부를 확인해야 하며, 복구 자격증명이 없는 상태에서 짧은 세션까지 만료되면 PKCE 로그인을 시작합니다.

갱신 요청 만들기

앱 재시작이나 짧은 세션 만료 시, 앞 절의 공유 잠금을 획득하고 저장소를 다시 읽습니다. 복구 자격증명의 미사용·절대 만료가 지나지 않았으면 다음 순서로 요청합니다.

  1. 저장소에 pending 요청이 있으면 다른 프로세스가 남긴 요청을 이어받습니다. 새 요청 키를 만들지 않습니다. pending 요청이 없는 새 논리 갱신에만 Idempotency-Key를 생성합니다. UUID 같은 고유 문자열을 사용하며 최대 128자입니다. 현재 자격증명·요청 키·시작 시각을 네트워크 요청 전에 영속 저장합니다.
  2. 해당 기기에 등록된 private key로 proof JWT를 서명합니다. 아래 표의 header와 claim을 넣습니다.
  3. 최신 sessionRefreshCredential 원문을 JSON 본문에 담아 Baron 공개 Backend URL로 POST합니다. 이 호출은 짧은 세션이 만료된 뒤에도 가능하며 X-Baron-Device-Session 헤더를 요구하지 않습니다.
Proof 위치 필드 넣을 값
JWT header typ baron-session-refresh+jwt
JWT header alg, kid 등록한 기기 JWK와 일치하는 알고리즘과 public JWK thumbprint
JWT claim iss, sub 둘 다 device:{deviceId}
JWT claim aud 서버의 BACKEND_PUBLIC_URL 뒤에 /api/v1/rp/installed/sessions/refresh를 붙인 정확한 URL
JWT claim htm, client_id POST, 요청 본문과 같은 RP client ID
JWT claim credential_hash base64url_no_padding(SHA256(UTF8(sessionRefreshCredential)))
JWT claim idempotency_key_hash base64url_no_padding(SHA256(UTF8(Idempotency-Key)))
JWT claim iat, exp Unix 초 단위 발급·만료 시각. TTL은 최대 5분이며 짧게 설정
JWT claim jti 매 HTTP 시도마다 새로 생성한 고유 값

기존 기기 등록 때 사용한 kid와 서명 알고리즘을 그대로 사용합니다. 서버는 public JWK의 SHA-256 thumbprint를 padding 없는 base64url로 인코딩한 kid를 검사합니다. 허용 알고리즘은 RS256, PS256, ES256, ES384, ES512, EdDSA이며 키 종류·크기·곡선도 일치해야 합니다. 구체적인 키 검증은 기기 public JWK 검증 코드를 참고하세요.

hash는 문자열 원문의 UTF-8 바이트로 계산합니다. JSON 따옴표나 줄바꿈을 포함하지 않습니다. proof의 iat가 서버 시각보다 30초 넘게 미래이면 거절됩니다. 예시의 호스트는 배포된 공개 URL로 바꾸며, reverse proxy 내부 주소를 aud에 사용하지 않습니다. 정확한 계약은 OpenAPI의 installed sessions endpoint를 따릅니다.

POST /api/v1/rp/installed/sessions/refresh HTTP/1.1
Host: sso.example.com
Content-Type: application/json
X-Baron-Device-Proof: <signed-proof-jwt>
Idempotency-Key: 484b2d71-3198-4ef5-a088-626081167c9c

{
  "clientId": "my-installed-rp",
  "deviceId": "7bd0c106-608e-4d57-8d37-c95b2bc94613",
  "sessionRefreshCredential": "<직전 성공 응답에서 받은 원문>"
}

응답 저장과 실패 처리

성공하면 Cache-Control: no-store와 함께 HTTP 200 JSON을 반환합니다. 형태는 최초 응답과 같으며 새 deviceSessionHandle, 새 sessionRefreshCredential, 새 만료 시각과 증가한 refreshGeneration을 받습니다. 예를 들어 최초 세대가 1이면 다음 성공 갱신은 2입니다. refreshAbsoluteExpiresAt는 최초 인증의 기한을 넘어 늘어나지 않습니다.

공유 잠금을 유지한 채 응답 전체의 세션·자격증명·기한·세대를 한 묶음으로 원자적으로 저장하고, pending 요청을 지운 뒤 잠금을 해제합니다. 다음 프로세스는 저장소의 새 값을 읽습니다. 응답을 받지 못했다면 pending 요청을 유지하고 60초 안에 같은 자격증명과 같은 Idempotency-Key, 새 jti로 서명한 proof로 재시도합니다. 서버가 이미 갱신을 완료했다면 같은 결과를 돌려주므로 세대가 다시 증가하지 않습니다. 저장 완료 후 다음 갱신에는 새 자격증명과 새 요청 키를 사용합니다.

HTTP / 응답 code RP 처리
400 invalid_device_proof 서명·audience·hash·시각·jti를 확인. 같은 proof를 재전송하지 않음
401 reauthentication_required 해당 로컬 인증 사용을 중단하고 PKCE 로그인 시작
401 session_refresh_idle_expired 미사용 기한이 지난 복구 자격 사용을 중단하고 PKCE 로그인 시작
401 session_refresh_absolute_expired 절대 기한이 지난 복구 자격 사용을 중단하고 PKCE 로그인 시작
409 refresh_in_flight Retry-After를 지키고 같은 논리 요청으로 재시도
409 idempotency_conflict 같은 요청 키에 다른 자격증명을 붙였는지 확인. 저장된 pending 요청과 대조
429 요청을 늦추고 응답 유실 재시도 기한도 확인
503 temporarily_unavailable / operation_indeterminate pending 요청 보존. 같은 요청으로 재시도하며, 이후 401이면 재로그인

일반 operation이 401 session_expired와 next_action=refresh_session을 반환하면 짧은 세션의 시간 만료입니다. 저장한 sessionRefreshCredential이 있고, 최초 발급 또는 마지막 갱신 응답의 refreshIdleExpiresAt와 refreshAbsoluteExpiresAt가 모두 지나지 않았다면 POST /api/v1/rp/installed/sessions/refresh를 먼저 호출하세요. 최종 유효성은 서버가 판단합니다. 자격증명이 없거나 두 기한 중 하나라도 지났거나 갱신이 위 표의 HTTP 401 코드로 거절되면 PKCE 로그인을 시작하세요. 503은 위 표의 재시도 절차를 따르며, 만료 안내 자체가 갱신 성공을 보장하지는 않습니다.

갱신 API는 확인된 만료 원인을 최상위 code로 반환합니다. 미사용 기한 만료는 session_refresh_idle_expired, 절대 기한 만료는 session_refresh_absolute_expired이며 둘 다 HTTP 401과 next_action=restart_login을 반환합니다. 두 기한이 모두 지났으면 절대 기한을 표시합니다. 명시적 폐기나 알 수 없는 자격은 기존 reauthentication_required를 유지하며 시간 만료로 표시하지 않습니다. message가 있으면 영문 그대로 표시하고 행동 판정에는 code와 선언된 next_action을 사용하세요.

#2268에서 기존 reauthentication_required 아래의 details.code·details.message를 최상위 code·message로 옮겼습니다. 기존 응답을 처리하던 RP는 위의 세 HTTP 401 코드를 모두 재로그인 대상으로 처리해야 합니다. 현재 응답에는 중첩 details가 없습니다. 오류 코드 안내에서 각 원인과 조치를 확인하세요.

일반 OAuth RP의 token endpoint는 별도 프로토콜 계약을 사용합니다. 확인된 inactive refresh token 또는 다른 client에 속한 token은 401 invalid_grant이며 새 로그인이 필요합니다. introspection 통신 장애나 잘못된 공급자 응답은 503 temporarily_unavailable입니다. invalid_grant만으로 만료와 폐기를 구분할 수 없으며 Baron의 details 필드는 이 응답에 추가하지 않습니다.

서버의 응답 재생 창은 성공 결과 생성 시각부터 60초입니다. RP는 서버 완료 시각을 알 수 없으므로 SDK처럼 영속 저장한 최초 요청 시작 시각부터 60초를 보수적인 재시도 한도로 사용합니다. 프로세스를 재시작하거나 담당 프로세스가 바뀌어도 이 시작 시각을 초기화하지 않습니다. 자격증명의 미사용·절대 만료도 별도로 확인합니다.

응답 유실 후 이 60초 재시도 한도를 넘겼다면 이전 자격증명을 새 요청 키로 다시 보내지 말고 PKCE 로그인을 시작합니다. 관리자나 외부 세션 종료에 따른 폐기는 다음 operation 또는 refresh 호출에서 확인합니다. 이번 연동에는 별도의 실시간 폐기 push가 없습니다.

앱 로그아웃은 같은 JSON 구조로 POST /api/v1/rp/installed/sessions/revoke를 호출합니다. 별도 폐기 요청 키를 영속 저장하고, proof의 typ을 baron-session-revoke+jwt, aud를 해당 revoke endpoint의 공개 URL로 바꿔 새로 서명합니다. 폐기 의도·자격증명·폐기 요청 키는 모든 프로세스가 보는 공유 보안 저장소에 기록합니다. 기기 키도 재시도에 필요하므로 유지합니다. pending 폐기가 있으면 자동 복구를 중단하고 폐기를 먼저 재시도합니다. 성공 응답은 본문 없는 HTTP 204이며, 이를 확인한 뒤 저장된 복구 자격증명과 pending 폐기 상태를 지웁니다. 401을 포함한 다른 응답을 폐기 완료로 간주하지 않습니다. 오프라인 폐기와 다중 프로세스 처리 순서는 앞 절을 따릅니다.