Files
llm-wiki/raw/official-docs/keycloak-authorization-services-realm-client-roles.md

9.5 KiB

title, source_type, url, archive_url, related_branches, related_projects, tags, created, last_reviewed
title source_type url archive_url related_branches related_projects tags created last_reviewed
Keycloak Authorization Services — Realm vs Client Roles, Permission Model, JWT Claims official-doc https://www.keycloak.org/docs/latest/authorization_services/index.html
feature-authentication-authorization-contract
ca-skeleton
authorization
keycloak
realm-roles
client-roles
JWT
permission-model
RBAC
ABAC
official-doc
2026-06-08 2026-06-08

Keycloak Authorization Services — Realm vs Client Roles, Permission Model, JWT Claims

Layer: raw/official-docs/ — Keycloak 공식 Authorization Services 문서 + JWT claim 구조 (realm_access / resource_access). feature-authentication-authorization-contract 의 IdP side permission model 결정의 근거.

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-authentication-authorization-contract Keycloak realm/client roles 을 JWT 로 전달받아 Spring Security ROLE_* authority 로 매핑하고, application-level permission check 는 별도 port 로 처리하는 설계 결정 근거

출처 / Source

Keycloak Authorization Services:

JWT claim mapping (community technical article, betweendata.io):

왜 저장했는지 / Why archived

Keycloak 이 JWT 에 realm_access.rolesresource_access[client].roles 두 가지 형태로 role 을 전달하고, Spring Security 는 이를 기본 지원하지 않아 custom JwtGrantedAuthoritiesConverter 가 필요함. 또한 Keycloak Authorization Services 의 fine-grained permission model 이 존재하지만, application-level authorization 과의 책임 분리를 결정하는 근거로 필요.

핵심 인용 / Key quotes (verbatim)

Keycloak Authorization Services

[§Authorization services overview] "A permission associates the object being protected with the policies that must be evaluated to determine whether access is granted."

[§Permission model — expression] "X CAN DO Y ON RESOURCE Z" — where X represents users/roles/groups, Y represents actions, Z represents protected resources.

[§Terminology — Resource] "A resource is part of the assets of an application and the organization. It can be a set of one or more endpoints, a classic web resource such as an HTML page, and so on."

[§Terminology — Scope] "A resource's scope is a bounded extent of access that is possible to perform on a resource...scope can also be related to specific information provided by a resource."

[§Fine-grained capabilities] "Policies are strongly related to the different access control mechanisms (ACMs) that you can use to protect your resources. With policies, you can implement strategies for attribute-based access control (ABAC), role-based access control (RBAC), context-based access control, or any combination of these."

Keycloak JWT Claim Structure (from community technical article)

[betweendata.io — JWT structure] "In the access token, realm roles appear under the realm_access claim containing a roles array" and "Resource roles are nested under resource_access, organized by client name, with each resource potentially containing its own roles collection."

{
  "realm_access": {
    "roles": ["admin", "user"]
  },
  "resource_access": {
    "my-app": {
      "roles": ["app-user"]
    }
  }
}

[betweendata.io — Spring Security gap] "Keycloak stores roles in custom claims like realm_access and resource_access, while Spring Security expects them in claims like roles or authorities."

[betweendata.io — custom converter] "implements a custom converter that extracts the roles from where they are by default," using a Converter<Jwt, Collection> that parses both claim levels.

[betweendata.io — prefix convention] Realm roles: "ROLE_realm_" prefix. Client roles: "ROLE_[CLIENT_NAME]_" prefix.

Spring Security Resource Server JWT (official)

[Spring Security JWT docs] "A JWT that is issued from an OAuth 2.0 Authorization Server will typically either have a scope or scp attribute, indicating the scopes (or authorities) it's been granted. When this is the case, Resource Server will attempt to coerce these scopes into a list of granted authorities, prefixing each scope with the string 'SCOPE_'."

[Spring Security JWT docs — custom claim] "As part of configuring a JwtAuthenticationConverter, you can supply a subsidiary converter to go from Jwt to a Collection of granted authorities." (via setAuthoritiesClaimName / setAuthorityPrefix)

Claims Extracted / 추출된 주장

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
KC-AUTHZ-C1 Keycloak Authorization Services 는 X CAN DO Y ON RESOURCE Z 로 표현되는 permission model 을 제공하며, ABAC / RBAC / context-based 를 모두 지원 [§permission expression] "X CAN DO Y ON RESOURCE Z" + [§fine-grained] "implement strategies for attribute-based access control (ABAC), role-based access control (RBAC)..." official-vendor-doc Keycloak 의 IdP-side fine-grained authorization 이 필요한 경우 application-level authorization 을 Keycloak 에 완전 위임하는 것이 항상 바람직하다는 것은 아님
KC-AUTHZ-C2 Keycloak JWT 에서 realm roles 은 realm_access.roles, client roles 은 resource_access[clientId].roles claim 에 위치 — Spring Security 기본 매핑과 불일치 [betweendata.io] "realm roles appear under the realm_access claim" + "Resource roles are nested under resource_access" engineering-blog (community article, NOT official-vendor-doc) Keycloak + Spring Security OAuth2 Resource Server 통합 모든 Keycloak 버전에서 이 claim 위치가 동일하게 유지된다는 것은 아님 — Keycloak 설정에 따라 다를 수 있음
KC-AUTHZ-C3 Spring Security 기본 JWT 파싱은 scope/scp claim 을 SCOPE_ prefix 로, role claim 은 자동 추출하지 않음 → Keycloak role 을 ROLE_* authority 로 쓰려면 custom JwtGrantedAuthoritiesConverter 필요 [Spring Security JWT docs] "Resource Server will attempt to coerce these scopes into a list of granted authorities, prefixing each scope with the string 'SCOPE_'" + custom converter needed official-vendor-doc Keycloak realm/client role → Spring ROLE_* authority 매핑 설계 이 매핑이 application-level permission check 의 완전한 대체가 된다는 것은 아님
KC-AUTHZ-C4 Keycloak Authorization Services (fine-grained) 는 resource + scope 기반으로 IdP 에서 permission 결정을 내리지만, application-level authorization logic 과의 책임 경계 분리 에 대한 공식 권고는 문서에 없음 [§Terminology — Scope] "A resource's scope is a bounded extent of access that is possible to perform on a resource" official-vendor-doc Keycloak Authorization Services 를 application authorization 대리로 쓰는 아키텍처 평가 이것이 실제 production 에서 권장/비권장인지 — 문서는 capabilities 만 기술

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것:
    • KC-AUTHZ-C1: Keycloak Authorization Services 는 ABAC/RBAC/context-based 지원
    • KC-AUTHZ-C2: JWT claim 위치 (realm_access.roles / resource_access[client].roles) — 단 community article 수준
    • KC-AUTHZ-C3: Spring Security 기본은 scopeSCOPE_*, Keycloak role 자동 추출 없음 (official)
  • 이 자료가 증명하지 않는 것:
    • Keycloak Authorization Services 를 쓰지 말아야 한다는 것
    • application-level AuthorizationPort 가 Keycloak Authorization Services 보다 낫다는 것
    • KC-AUTHZ-C2 는 community article 기반 — official Keycloak token 구조 문서로 확인 필요
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
    • ca-skeleton 에서 사용하는 Keycloak 버전의 realm_access / resource_access claim 위치가 변경되지 않았는지
    • application-level permission 만으로 충분한지 vs Keycloak Authorization Services UMA flow 까지 도입할지의 복잡도 trade-off

메모 / Notes

  • Keycloak Authorization Services vs. application-level: Keycloak Authorization Services 는 강력하지만 복잡함 (UMA 2.0, policy evaluation endpoint, resource server registration). 단순 permission check 에는 application-level AuthorizationPort 가 훨씬 간단하고 테스트하기 쉬움
  • realm roles vs client roles: realm roles = organization-wide (예: ADMIN, USER). client roles = app-specific (예: portfolio:write). 이 프로젝트에서 ROLE_* authority 로 매핑하는 것은 realm roles 대상이 일반적
  • 주의: KC-AUTHZ-C2 는 engineering blog (betweendata.io) 기반 — official Keycloak 문서 (https://www.keycloak.org/docs/latest/server_admin/index.html#assigning-permissions-using-roles-and-groups) 로 별도 확인 권장