Skip to content

필사 모드: Keycloak 26.7 — SCIM 프리뷰 승격, 외부 Infinispan 없는 멀티클러스터 v2, 그리고 업그레이드에서 밟기 쉬운 것들

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

들어가며 — 분기마다 하나씩, 이번엔 26.7

Keycloak은 요즘 석 달 간격으로 마이너를 냅니다. GitHub 릴리스 기준으로 26.5.0이 2026년 1월 6일, 26.6.0이 4월 8일, 그리고 26.7.0이 7월 9일에 나왔습니다. 마이너 하나가 나올 때마다 릴리스 노트만 훑고 넘어가기엔 이번 릴리스는 운영자 입장에서 걸리는 게 많습니다 — 오래 기다린 기능 둘(SCIM, 외부 캐시 없는 멀티클러스터)이 프리뷰로 올라왔고, 업그레이드 가이드의 breaking/notable 목록이 유난히 깁니다.

이 글은 공식 릴리스 노트와 저장소의 원문 adoc(릴리스 노트, 업그레이드 가이드), 그리고 기능 플래그의 실제 정의인 Profile.java를 대조해서 정리한 운영 관점 읽기입니다. Keycloak 26 아키텍처 자체가 처음이라면 Keycloak 26 아키텍처 딥다이브를 먼저 보는 편이 낫습니다.

SCIM API — 4년 열려 있던 이슈가 코어로 (프리뷰)

SCIM(System for Cross-domain Identity Management)은 사용자·그룹 같은 아이덴티티 리소스를 시스템 간에 표준 REST API로 읽고 쓰는 프로토콜입니다(스키마는 RFC 7643, 프로토콜은 RFC 7644). Okta나 Entra ID 같은 상용 IdP에서는 당연하게 여겨지는 기능인데, Keycloak 코어에는 없었습니다. 2022년 8월에 열린 SCIM 지원 이슈가 리액션 300개를 모으며 아직도 열려 있고, 그동안 이 공백은 scim-for-keycloak 같은 서드파티 확장이 메워 왔습니다.

이번에 그 공백이 코어에서 채워지기 시작했습니다. 타임라인을 코드로 확인하면 이렇습니다 — scim-api 기능 플래그는 26.6.0의 Profile.java에 experimental로 조용히 들어왔고(26.6.0 릴리스 노트에는 언급이 없습니다), 26.7.0에서 프리뷰로 승격됐습니다. 기본 비활성이라 --features=scim-api로 켜야 하고, 켠 뒤에도 realm 설정에서 realm별로 다시 토글해야 합니다.

구현 범위는 관리 가이드의 SCIM 장 기준으로 다음과 같습니다.

  • 사용자·그룹의 생성/조회/수정/PATCH/삭제 전체와 그룹 멤버십 관리
  • SCIM 필터 문법 전체와 페이지네이션
  • Enterprise User 확장(RFC 7643 4.3절)과 User Profile 속성 매핑을 통한 커스텀 스키마 확장
  • 스키마 디스커버리 엔드포인트

엔드포인트는 realm 단위로 열립니다.

/realms/<realm-name>/scim/v2/ServiceProviderConfig
/realms/<realm-name>/scim/v2/ResourceTypes
/realms/<realm-name>/scim/v2/Schemas
/realms/<realm-name>/scim/v2/Users
/realms/<realm-name>/scim/v2/Groups

권한 모델은 새로 만들지 않고 Admin REST API와 같은 realm-management 롤을 그대로 씁니다. 사용자 쓰기는 manage-users, 읽기는 view-users, 검색은 query-users/query-groups — 이미 Admin API용 서비스 계정이 있다면 추가 설정 없이 SCIM도 됩니다. 호출은 confidential 클라이언트만 허용되고, public 클라이언트는 거부됩니다.

설계에서 눈에 띄는 부분은 관리자 리소스 보호입니다. SCIM 클라이언트는 보통 광범위한 관리 권한으로 돌기 때문에, 침해당한 프로비저닝 클라이언트가 관리자 계정을 지우거나 관리자 그룹에 사용자를 밀어 넣는 시나리오를 문서가 명시적으로 막습니다 — 관리 롤을 가진 사용자·그룹은 SCIM으로 조회하면 최소 표현(id, schemas, userName 정도)만 나오고, 쓰기는 403으로 거부됩니다. 관리자 계정은 Admin 콘솔과 Admin REST API로만 만질 수 있습니다.

정직하게 한계를 적으면 — 지금 들어온 것은 Keycloak이 SCIM 서버가 되는 방향 하나입니다. HR 시스템이나 아이덴티티 거버넌스 플랫폼이 Keycloak에 사용자를 넣고 빼는 인바운드 프로비저닝은 이걸로 됩니다. 반대로 Keycloak이 SCIM 클라이언트가 되어 외부 SCIM 제공자에서 사용자를 연합해 오는 것은 별도 이슈로 아직 열려 있고, 문서도 외부 SCIM 서비스 제공자로부터의 사용자 연합과 푸시 기반 실시간 이벤트를 향후 릴리스 계획으로만 적어 둡니다. Keycloak에서 다운스트림 앱으로 밀어 주는 아웃바운드 프로비저닝도 이번 범위에 없습니다 — 그건 여전히 확장의 영역입니다. 그리고 프리뷰는 프리뷰입니다. 지원 대상이 아니며, 최종 형태가 바뀔 수 있습니다.

멀티클러스터 v2 — 외부 Infinispan 없이 (프리뷰)

지금까지 Keycloak의 멀티 사이트 HA(v1)는 사이트 간 세션 복제를 위해 외부 Infinispan(Data Grid) 클러스터를 따로 배포·운영해야 했고, 자동 페일오버를 위한 벤더 특화 fencing 인프라까지 요구했습니다. Keycloak HA 클러스터링 가이드에서 다뤘던 그 구조입니다. 운영해 본 사람은 알겠지만, 인증 서버의 HA를 위해 캐시 클러스터라는 또 하나의 분산 시스템을 돌보는 비용이 만만치 않습니다.

26.7의 멀티클러스터 v2는 그 외부 의존성을 통째로 걷어냅니다. 아키텍처는 이렇게 바뀝니다.

  • Keycloak 인스턴스들이 내장 Infinispan 캐시로 클러스터 간 직접 연결됩니다.
  • 동기 복제되는 데이터베이스가 단일 진실 공급원이 됩니다. 기능 플래그 이름이 stateless인 이유가 이것입니다 — Profile.java의 정의 그대로, 인증 세션·액션 토큰·로그인 실패 데이터를 DB에 저장해서 여러 클러스터가 DB만으로 연결되게 합니다.
  • 사이트 간 캐시 무효화는 DB 기반 outbox 패턴으로 처리됩니다.
  • 로드 밸런서가 외부 fencing 없이 사이트 다운을 감지합니다.

여기까지만 들으면 지리적 DR까지 되는 것처럼 들리는데, 공식 가이드가 못을 박아 둔 제약을 그대로 옮기면 이렇습니다.

  • 단일 리전 또는 그에 준하는 저지연 환경 전용입니다. 동기 복제되는 고가용 데이터베이스가 필수이고, 클러스터에서 DB까지의 읽기/쓰기/커밋 지연은 5ms 미만 권장, 10ms 미만 필수입니다. 대륙 간 액티브-액티브 DR을 기대하면 안 됩니다.
  • 팀이 정기 테스트하는 구성(벤더 자체 측정)은 같은 AWS 리전 안의 단일 AZ OpenShift(ROSA HCP) 클러스터 두 개 + 가용 영역 간 동기 복제 리더를 둔 Aurora PostgreSQL 17.5 + AWS Global Accelerator이고, 테스트 부하는 사용자 100만 명에 초당 300 요청입니다. 이 범위를 넘는 규모는 직접 검증하라고 명시합니다.
  • 장애 시나리오에 따라 수 분의 다운타임이 있을 수 있고, DB 벤더에 따라 수동 개입이 필요할 수 있습니다. 노드 장애 감지는 기본값 기준 1분 이내입니다.

운영 관점에서 하나 더 — Profile.java에서 이 기능은 FeatureUpdatePolicy.SHUTDOWN으로 선언돼 있습니다. 플래그를 켜거나 끌 때 롤링이 안 되고 클러스터 전체 셧다운이 필요하다는 뜻입니다. 이미 돌고 있는 프로덕션에 무중단으로 끼워 넣는 종류의 기능이 아닙니다.

요약하면 v2는 "외부 Infinispan 운영을 없앤 리전 내 다중 클러스터 가용성"이지, "멀리 떨어진 두 데이터센터"가 아닙니다. 대신 얻는 것은 분명합니다 — 관리할 분산 시스템이 하나 줄고, Kubernetes나 AWS 같은 특정 환경 요구도 사라집니다. 부하가 테스트 범위 안이고 DB를 동기 복제로 운영할 수 있는 조직이라면, v1의 운영 복잡도와 맞바꿀 가치가 있는 트레이드입니다.

여담 하나. 태그 시점의 릴리스 노트 원문은 이 기능을 하이라이트에서는 프리뷰로, 본문 제목에서는 experimental로 적는 불일치가 있었고(main 브랜치에서 프리뷰로 정리됐습니다), 코드의 Profile.java는 처음부터 PREVIEW였습니다. 릴리스 노트와 코드가 갈릴 때는 코드가 맞습니다.

Organizations — 멀티테넌시 위임이 현실적으로

멀티테넌트 SaaS SSO 아키텍처에서 다룬 것처럼, Keycloak의 Organizations는 realm 하나 안에서 여러 테넌트(조직)를 관리하는 기능입니다. 그런데 지금까지 조직을 관리하려면 manage-realm이라는 고권한 롤이 필요했습니다 — 테넌트 관리자에게 realm 전체 관리 권한을 주는 셈이라, 위임이라고 부르기 민망한 구조였습니다.

26.7이 이걸 손봤습니다.

  • 전용 realm 관리 롤 세 개가 생겼습니다: manage-organizations(조직 전체 읽기·쓰기), view-organizations(읽기 전용), query-organizations(목록·검색만). 기존 query-users/query-clients 패턴과 같은 결입니다. manage-realm은 하위 호환을 위해 여전히 조직 관리 권한을 함축합니다.
  • 조직이 Fine-Grained Admin Permissions의 1급 리소스 타입이 됐습니다. 특정 조직 하나만 관리할 수 있는 위임 관리자를 만들 수 있고, FGAP가 켜져 있으면 조직 멤버 조회도 사용자 수준 권한을 존중해서 볼 수 있는 멤버만 반환합니다.
  • 조직 그룹에 realm/client 롤을 매핑할 수 있게 됐습니다. 조직 그룹에 롤을 한 번 달면 멤버 전원의 realm_access/resource_access 클레임에 자동 반영되고, Organization Group Membership 프로토콜 매퍼의 옵션을 켜면 organization 클레임 안에 조직별로 정리해 넣을 수도 있습니다. 수백 명 규모 테넌트에서 멤버마다 롤을 다는 대신 그룹 단위로 관리하라는 이야기입니다.

브레이킹도 하나 딸려 왔습니다. 조직 멤버 목록 API가 이제 기본으로 brief 표현을 반환합니다. 전체 사용자 표현이 필요하면 쿼리 파라미터를 명시해야 합니다.

GET /admin/realms/{realm}/organizations/{id}/members?briefRepresentation=false

조직 초대 목록의 email/firstName/lastName 필터도 부분 일치에서 대소문자 무시 정확 일치로 바뀌었습니다 — 부분 일치가 필요하면 search 파라미터를 쓰라고 안내합니다. 이 API들에 의존하는 자동화가 있다면 응답과 필터 동작이 달라졌는지 먼저 확인하십시오.

업그레이드에서 밟기 쉬운 것들

이번 업그레이드 가이드에서 운영자가 실제로 밟을 만한 것들을 골랐습니다. 전체 목록은 업그레이드 가이드 원문을 보십시오.

PostgreSQL 비동기 커밋이 기본으로 켜집니다. persisted user sessions, client sessions, login failures, events처럼 휘발성 테이블만 갱신하는 트랜잭션은 이제 PostgreSQL의 async commit으로 처리됩니다(로그아웃은 여전히 동기 커밋 강제). 성능을 위한 선택인데, 의미를 정확히 알아야 합니다 — PostgreSQL 문서 기준으로 비동기 커밋은 WAL이 디스크에 플러시되기 전에 커밋 성공을 돌려주며, 서버가 크래시하면 그 사이 커밋은 유실됩니다. 유실 창은 최대 wal_writer_delay(기본 200ms)의 3배입니다. 데이터가 깨지는 게 아니라 마지막 1초 미만의 세션·이벤트 쓰기가 사라지는 것이고, 사용자 입장에서는 재로그인으로 끝납니다. 다만 events 테이블이 포함된다는 점은 짚을 만합니다 — 크래시 직전의 로그인 이벤트가 감사 로그에서 빠질 수 있다는 뜻이라, 감사 요건이 엄격한 환경이라면 --spi-connections-jpa--quarkus--async-commit=false로 옵트아웃할지 판단이 필요합니다.

X.509 클라이언트 인증에 CA Subject DN 옵션이 생겼고, 사실상 필수가 됩니다. mTLS로 클라이언트를 인증하는 경우, 이제 관리 콘솔에서 신뢰 앵커 CA의 subject DN을 지정하는 옵션이 강제됩니다. 기존 설정은 당장은 동작하지만, 다음 메이저부터 서버 측 검증이 들어가 이 옵션 없는 생성·수정·임포트가 거부됩니다. 정확한 DN 대신 정규식으로 인증서를 매칭하던 옵션도 함께 폐기 예고됐습니다. TLS 종료 프록시 뒤에서 헤더로 인증서를 넘기는 구성이라면 truststore가 클라이언트 인증서 체인을 검증할 수 있게 맞춰져 있는지도 다시 확인해야 합니다.

셀프 등록 흐름이 바뀝니다. realm에서 셀프 등록과 Verify Email을 함께 켠 경우, 등록 폼에서 비밀번호 필드가 기본으로 사라집니다. 사용자는 프로필만 등록하고, 이메일을 검증한 뒤에 비밀번호(또는 OTP, 패스키)를 설정합니다. 검증 안 된 이메일로 크리덴셜부터 만드는 순서를 뒤집은 것인데, 등록 UX와 문서·스크린샷이 통째로 달라지는 변경입니다. 예전 동작으로 되돌리는 스위치가 있지만 deprecated로 표시돼 있습니다.

나머지는 압축해서 나열합니다.

  • 셧다운 타임아웃이 1초에서 10초로 늘었고, 분산 캐시 리밸런스 완료를 기다린 뒤 내려갑니다. 오케스트레이터의 종료 유예(terminationGracePeriodSeconds 등)와 맞춰 두십시오. shutdown-timeout 옵션으로 조정 가능합니다.
  • 새로 생성되는 클라이언트 시크릿이 항상 86자입니다(HS512 엔트로피 확보 목적). 기존 시크릿은 그대로지만, 시크릿을 저장하는 쪽에 최대 길이 제약이 있다면 늘려야 합니다.
  • 세션 쿠키 해시가 SHA-256에서 SHA-384로, 신규 aes-generated 키 기본 크기가 128비트에서 256비트로 올라갔습니다(둘 다 CNSA 2.0 정렬 목적, 기존 세션·기존 realm은 영향 없음).
  • 26.5.4에서 도입 즉시 deprecated였던 view-system 관리 롤이 보안상 이유로 제거됐습니다. 서버 전체 정보 조회는 이제 master realm의 manage-realm 보유자로 제한됩니다.
  • FreeMarker가 2.3.32 기본값으로 올라갔습니다. 레거시 지시자나 ?api 같은 내부 접근에 기대던 커스텀 로그인 테마는 업그레이드 후 반드시 테스트하십시오. 로그인 테마의 버튼 배치도 바뀌었습니다.
  • DPoP가 implicit/hybrid 플로우에서 거부됩니다. 프런트 채널로 액세스 토큰이 나가는 플로우에서는 sender-constrained 모델이 성립하지 않는다는 이유로, 해당 조합은 이제 에러입니다.
  • Admin REST API에서 ID로 사용자를 조회할 때 서비스 계정이 더는 포함되지 않고, Identity Provider의 alias는 생성 후 변경 불가가 됐습니다.
  • Authorization Services의 리소스 URI 템플릿 검증이 엄격해졌습니다. 경로 중간 와일드카드처럼 원래 동작하지 않던 패턴이 이제 생성·수정 시 거부되므로, 업그레이드 전에 리소스들의 uris 필드를 점검하라고 가이드가 사전 점검 쿼리까지 제공합니다.

폐기 레이더 — 지금 끄거나 갈아탈 것

  • Identity Brokering API V1이 deprecated 됐습니다. 대체인 V2는 사용자에게 broker 롤을 다는 대신 클라이언트 단위 인가(외부 토큰 조회 허용 스위치 + IdP 허용 목록)로 바뀌고, confidential 클라이언트만 허용하며, POST + 표준 JSON 응답을 씁니다. V2는 이번 릴리스에서 지원되지만 기본 비활성이고, V1은 아직 기본 활성입니다 — 미래 릴리스에서 V1이 제거되고 V2가 기본이 될 예정이니, 외부 IdP 토큰을 꺼내 쓰는 애플리케이션이 있다면 지금부터 V2로 옮기는 게 맞습니다.
  • Twitter Identity Broker가 제거 예고됐습니다. 레거시 OAuth 1.0a 엔드포인트에 의존하기 때문입니다. X의 OAuth 2.0 엔드포인트에 generic OAuth v2 IdP를 설정하는 것으로 갈아타고, 안 쓴다면 --features-disabled=twitter-broker로 꺼 둘 수 있습니다.
  • OIDC 클라이언트의 Bearer-only 스위치가 deprecated 됐습니다. 콘솔에서는 이미 사라졌고 REST로만 설정 가능했는데, 그마저 막힐 예정입니다. 그랜트 없는 OIDC 클라이언트로 같은 목적을 달성할 수 있습니다.
  • WebAuthn 정책의 Require Discoverable Credential 옵션이 deprecated 됐습니다. 새 Discoverable Credential 옵션은 WebAuthn 명세의 residentKey 값(required/preferred/discouraged)을 그대로 지원합니다 — Yes/No 강제로는 표현할 수 없던 preferred가 iCloud Keychain, Google Password Manager, 1Password 같은 패스키 제공자와의 호환성에 중요합니다. 패스키 생태계가 지금 어디까지 왔는지는 패스키 크리덴셜 익스체인지 정리에서 다뤘습니다.
  • SHA-1이 Keycloak 27에서 전면 제거됩니다. NIST의 SHA-1 은퇴 계획(2030년 완전 퇴역)을 근거로, 업그레이드 가이드는 Keycloak 안에서 SHA-1을 이미 은퇴한 것으로 간주하고 SHA-2/SHA-3 계열로 지금 옮기라고 적시합니다. SAML 서명 알고리즘이나 오래된 연동에서 SHA-1을 쓰고 있다면 27이 나오기 전에 정리해야 합니다.

그 밖의 표준 실험들 — 한 단락씩만

이번 릴리스에는 experimental 딱지를 단 표준 구현이 유난히 많습니다. 전부 기본 비활성이고, experimental은 프리뷰보다도 앞 단계라는 점을 전제로 훑습니다.

  • Shared Signals Framework 송신자(ssf): 로그아웃·크리덴셜 변경·계정 비활성화 같은 보안 이벤트를 서명된 SET(RFC 8417)으로 다운스트림에 거의 실시간 푸시합니다. CAEP 1.0과 RISC 1.0 프로파일, push(RFC 8935)/poll(RFC 8936) 전달을 지원하고, durable outbox로 재시작에도 이벤트를 잃지 않게 설계됐습니다. 토큰 리프레시 때까지 세션 무효화를 모르는 고전적 공백을 겨냥한 기능입니다.
  • AuthZEN Evaluation API(authzen): OpenID AuthZEN 1.0의 PDP 역할을 구현했습니다. subject/resource/action을 보내면 기존 Authorization Services 정책으로 permit/deny를 돌려줍니다. 단건·배치 평가 모두 지원합니다.
  • Identity Assertion JWT Grant(identity-assertion-jwt): 조직 간 인증 서버를 넘나들 때 재인증 없이 토큰을 받는 ID-JAG 드래프트의 부분 구현입니다. 현재는 수신 측 역할만 구현돼 있어 전체 플로우는 아직 안 됩니다.
  • 토큰 교환 위임(token-exchange-delegation): 게이트웨이가 다운스트림에서 사용자를 대신해 행동하는 위임 시나리오용으로, delegation 파라미터화 스코프가 사용자 동의를 요구하고 리프레시마다 재평가됩니다. 토큰 교환의 배경은 RFC 8693 토큰 교환과 위임을 참고하십시오.
  • Admin API v2(client-admin-api:v2): 엄격한 검증과 정확한 OpenAPI 명세를 갖춘 새 관리 API의 첫 리소스로 클라이언트 관리가 들어왔습니다. Operator가 이를 써서 KeycloakOIDCClient/KeycloakSAMLClient 커스텀 리소스로 클라이언트를 선언적으로 관리합니다. 기존 Admin REST API의 느슨한 검증과 부정확한 스펙이라는 오랜 불만에 대한 답이 시작된 셈입니다.

프리뷰에서 정식 지원으로 승격된 것은 SAML 클라이언트의 step-up 인증 하나입니다. OIDC에만 있던 인증 컨텍스트 요구가 SAML SP에도 열렸습니다.

그래서 언제 올리고, 무엇을 켜나

정리하면 이렇게 판단하겠습니다.

  • 업그레이드 자체는 마이너 릴리스이고 위 목록이 전부 관리 가능한 수준이니 미룰 이유가 없습니다. 다만 올리기 전에 X.509 CA Subject DN 추가, 클라이언트 시크릿 길이 제약, 커스텀 테마 테스트, async commit 옵트아웃 여부, 셀프 등록 흐름 변화 네다섯 가지는 체크리스트로 도십시오.
  • SCIM 프리뷰는 스테이징에서 켜 볼 가치가 충분합니다. 특히 Admin REST API로 프로비저닝 스크립트를 짜서 쓰던 조직이라면, 표준 프로토콜 + 기존 권한 모델 + 관리자 보호까지 갖춘 이 방향이 장기적으로 옳습니다. 다만 프로덕션 의존은 preview가 supported로 승격된 뒤가 맞고, Keycloak이 클라이언트가 되는 방향(외부 SCIM 연합, 다운스트림 푸시)은 아직 없다는 걸 전제로 설계하십시오.
  • 멀티클러스터 v2는 지금 v1(외부 Infinispan) 운영에 지쳐 있고, 단일 리전 + 동기 복제 DB 조건을 맞출 수 있는 조직에게 실질적 단순화입니다. 반대로 지리적 DR이 요구사항이라면 이 기능은 답이 아닙니다 — 10ms 미만 DB 지연 요구가 그 선을 긋습니다. 켜고 끌 때 전체 셧다운이 필요하다는 점까지 계획에 넣으십시오.
  • 조직 관리 롤 세 개는 프리뷰가 아니라 이번 릴리스의 조용한 실속입니다. 테넌트 관리자에게 manage-realm을 주고 있었다면 지금 바로 회수하고 manage-organizations 이하로 좁히는 것이 이번 업그레이드에서 얻을 수 있는 가장 확실한 보안 개선입니다.

마치며

Keycloak 26.7은 헤드라인(SCIM, 멀티클러스터 v2)만 보면 프리뷰 잔치지만, 그 아래에 깔린 방향은 일관됩니다 — 서드파티 확장과 외부 인프라가 메워 온 공백을 코어 표준 구현으로 흡수하고(SCIM, SSF, AuthZEN), 고권한 롤을 쪼개고(조직 관리 롤, view-system 제거), 오래된 느슨함을 조입니다(X.509 CA DN, URI 템플릿 검증, SHA-1 퇴역 예고). 자가 호스팅 IdP를 운영하는 입장에서는 반가운 방향이고, 그 대가는 업그레이드 가이드가 길어지는 것뿐입니다. 릴리스 노트만 읽고 넘어가지 말고, 업그레이드 가이드를 체크리스트 삼아 한 번 도는 것을 권합니다.

참고 자료

현재 단락 (1/81)

Keycloak은 요즘 석 달 간격으로 마이너를 냅니다. GitHub 릴리스 기준으로 26.5.0이 2026년 1월 6일, 26.6.0이 4월 8일, 그리고 [26.7.0이 7월 ...

작성 글자: 0원문 글자: 11,429작성 단락: 0/81