세션, Token 수명과 로그아웃
“로그아웃했다”는 한 문장만으로는 보안 결과를 알 수 없다. 브라우저의 앱 cookie를 지웠는지, Keycloak SSO session을 끝냈는지, 다른 client에 알렸는지, 기존 access token이 만료됐는지를 나눠 본다.
이 장에서 처음 나오는 말4개
SSO user session- 한 realm에서 사용자의 전체 로그인 상태. 방문한 client session들의 부모다.
client session- SSO session 안에서 특정 client의 code·refresh와 연결된 상태. 앱 자체 session과 다르다.
RP-Initiated Logout- 앱이 OIDC 표준 logout endpoint로 브라우저를 보내 IdP 세션 종료를 요청하는 방식.
offline token- 사용자가 온라인이 아니어도 장기 작업이 새 access token을 얻도록 별도 offline session에 연결된 credential.
큰 그림
섹션 제목: “큰 그림”| 층 | 보관 위치 | 끝나는 대표 조건 |
|---|---|---|
| 앱 A/B session | 각 앱의 cookie·서버 저장소 | 앱 local logout, 앱 session 만료·container 재시작 |
| Keycloak client session | Keycloak session 저장소 | client/SSO session 종료, idle·max 만료 |
| Keycloak SSO user session | Keycloak DB·cache | RP/admin logout, SSO idle·max 만료 |
| access token JWT | token을 가진 client | exp 도달 또는 소비자의 별도 revocation 정책 |
Keycloak 26 계열은 persistent user sessions가 기본이므로 정상 DB를 유지한 서버 재시작만으로 모두 로그아웃된다고 전제하지 않는다. 반대로 이 실습 앱의 memory session은 앱 container 재시작 때 사라진다.
이 장에서 답할 질문
섹션 제목: “이 장에서 답할 질문”- access·refresh token과 세션 timeout은 어떻게 연결되는가?
- 앱 logout과 Keycloak logout은 무엇이 다른가?
- 계정·권한을 바꿨는데 기존 접근이 남는 이유는 무엇인가?
수명 다이얼을 분리한다
섹션 제목: “수명 다이얼을 분리한다”Keycloak session 관리 문서는 SSO Session Idle/Max, Client Session Idle/Max, access token lifespan과 offline session을 별도 값으로 설명한다.
| 값 | 질문 |
|---|---|
| Access Token Lifespan | 이미 발급된 bearer를 소비자가 언제까지 받을까? |
| SSO Session Idle | refresh나 인증 활동 없이 얼마 뒤 전체 로그인 상태를 끝낼까? |
| SSO Session Max | 활동과 무관하게 전체 session을 언제 끝낼까? |
| Client Session Idle/Max | 특정 client의 refresh 가능 기간을 더 짧게 제한할까? |
| Offline Session Idle/Max | 사용자 부재 중 장기 작업 credential을 얼마나 유지할까? |
refresh는 기존 access token을 연장하는 것이 아니라 Keycloak session과 현재 사용자 상태를 확인해 새 token을 받는 요청이다. refresh rotation을 켜면 응답의 새 refresh token을 원자적으로 저장해야 한다. offline token은 일반 logout 뒤에도 쓰려는 예외이므로 최소 client·scope와 별도 폐기 절차가 필요하다.
로그아웃의 네 결과
섹션 제목: “로그아웃의 네 결과”| 작업 | 앱 cookie | Keycloak SSO | 다른 client | 기존 access token |
|---|---|---|---|---|
| 앱 local logout | 해당 앱만 제거 | 보통 유지 | 유지 | API가 exp까지 받을 수 있음 |
| RP-Initiated Logout | 앱도 후처리 필요 | 종료 요청 | front/backchannel 지원에 따라 통지 | 자동 즉시 회수 아님 |
| Admin user session logout | 앱 구현에 따라 잔존 | 대상 session 종료 | adapter·logout 설정에 따라 통지 | 로컬 JWT 검증자는 exp까지 수용 가능 |
| 앱 container 재시작 | memory session 제거 | 유지 | 영향 없음 | 이미 외부에 전달된 token은 별개 |
Keycloak OIDC logout endpoint는 표준 logout 또는 관리·account 경로를 권한다. backchannel logout URL을 설정했다면 앱은 서명된 logout token을 검증하고 자기 session을 찾아 끝내야 한다.
변경·장애 실습에서 본 결과
섹션 제목: “변경·장애 실습에서 본 결과”P09에서 group 제거는 새 로그인·refresh token의 admin role을 없앴지만 기존 JWT와 앱 session token은 만료 전까지 유지됐다. alice 계정 비활성화는 새 로그인과 refresh를 거부했지만 기존 JWT는 유지됐다. LDAP 중단 중에는 새 외부 인증이 실패했지만 이미 만든 client session의 refresh는 고정된 cache 조건에서 성공했다. 이는 단일 node와 해당 설정의 관찰 결과이며 모든 cache·cluster 구성의 보장이 아니다.
- SSO user session, client session, 앱 session, JWT는 서로 다른 수명과 저장 위치를 가진다.
- refresh는 현재 session 상태로 새 token을 발급받는 과정이며 access token 자체의 수명 연장이 아니다.
- 앱 local logout과 RP-Initiated·backchannel logout의 범위는 다르다.
- 세션을 끝내도 로컬 검증되는 기존 JWT는
exp까지 남을 수 있으므로 짧은 수명과 소비자 정책을 함께 설계한다.