--- title: Keycloak — Configuring the hostname (v2 hostname guide, iss claim validation) source_type: official-doc url: https://www.keycloak.org/server/hostname archive_url: status: raw confidence: high tags: [hostname, hostname-strict, iss-claim, jwt-validation, kc-hostname, keycloak, keycloak-patterns, oidc-discovery, p3a-single-ec2, p3b-single-ec2-google, public-uri, security] related_projects: [keycloak-patterns] related_branches: [feature-keycloak-patterns, feature-keycloak-single-ec2-google-federation, feature-keycloak-single-ec2-no-google, feature-keycloak-iss-claim-hostname-mismatch, feature-keycloak-https-termination-caddy-nginx, feature-keycloak-reverse-proxy-headers] created: 2026-05-25 last_reviewed: 2026-05-27 --- # Keycloak — Configuring the hostname > Layer: `raw/official-docs/` — Keycloak Server Guides "Hostname v2" 페이지 발췌. > `iss` claim 생성 / fraudulent issuer 방어 / frontchannel-backchannel URL 분리의 1차 근거. ## Parent / 활용 branch (필수) | Branch | 이 자료가 정당화하는 결정 | |---|---| | [[raw/branch-notes/feature-keycloak-patterns]] | keycloak-patterns root — hostname-strict 활성 + 명시적 hostname 설정의 모든 P 변형 baseline | | [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] | P3B 단일 EC2 + Google federation 에서 public DNS → `KC_HOSTNAME` 명시 결정 | | [[raw/branch-notes/feature-keycloak-single-ec2-no-google]] | P3A 단일 EC2 (Google 없음) 에서 `KC_HOSTNAME=localhost` 단순화 결정 | | [[raw/branch-notes/feature-keycloak-iss-claim-hostname-mismatch]] | `iss` mismatch 디버깅 시 hostname 옵션과의 인과 관계 정리 (frontchannel vs backchannel URL) | | [[raw/branch-notes/feature-keycloak-https-termination-caddy-nginx]] | reverse proxy 가 Host header 를 overwrite 하는 경우 `hostname-strict` 유지 결정 근거 | | [[raw/branch-notes/feature-keycloak-reverse-proxy-headers]] | hostname + proxy-headers 조합으로 발급 URL 결정 메커니즘 | ## 컨텍스트 P3A/P3B 의 핵심 함정: container service name (`keycloak`) 과 external hostname (`localhost` 또는 public DNS) 의 mismatch 가 token `iss` claim 검증 실패로 직결. `KC_HOSTNAME` 명시가 의무이며, 이는 fraudulent issuer 방어를 위한 공식 보안 조치. ## 출처 / Source - 원본 URL: https://www.keycloak.org/server/hostname - 아카이브 URL: (미수집) - 저자 / 조직: Keycloak (Red Hat) — Server Guides - 발행일: rolling docs (현재 26.x, v2 hostname guide 적용 중) - 마지막 확인일: 2026-05-27 ## 핵심 인용 / Key quotes (verbatim) > [§Backchannel] "Keycloak has the capability to offer a separate URL for backchannel requests, enabling internal communication while maintaining the use of a public URL for frontchannel requests." > [§Default behavior] "By default, Keycloak mandates the configuration of the `hostname` option and does not dynamically resolve URLs. This is a security measure." > [§Security rationale] "By explicitly setting the `hostname` option, we avoid a situation where tokens could be issued by a fraudulent issuer." > [§hostname-backchannel-dynamic] "If set to true, `hostname` option needs to be specified as a full URL." > [§hostname-strict] "Should always be set to true in production, unless your reverse proxy overwrites the Host header." > [§Relevant options table] `hostname-strict` default: `true` ## Claims Extracted / 추출된 주장 | Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | |---|---|---|---|---|---| | KC-HOST-C1 | Keycloak 은 backchannel 요청에 별도 URL 을 제공할 수 있으며, frontchannel public URL 과 internal communication URL 을 분리 가능 | [§Backchannel] "Keycloak has the capability to offer a separate URL for backchannel requests, enabling internal communication while maintaining the use of a public URL for frontchannel requests." | `official-vendor-doc` | container 내부 vs 외부 access 가 다른 토폴로지 (예: docker-compose, k8s) | backchannel URL 의 정확한 설정 옵션 이름 (`KC_HOSTNAME_BACKCHANNEL_DYNAMIC` 등) 의 자세한 동작은 다른 section | | KC-HOST-C2 | Keycloak 의 기본 동작은 `hostname` 옵션 설정을 **의무화** 하며 dynamic URL resolution 을 차단 (보안 조치) | [§Default behavior] "By default, Keycloak mandates the configuration of the `hostname` option and does not dynamically resolve URLs. This is a security measure." | `official-vendor-doc` | Keycloak 모든 deployment | hostname 미설정 시의 정확한 startup 동작 (실패 vs 기본값 추론) 은 본 인용에 없음 | | KC-HOST-C3 | `hostname` 옵션 명시는 **fraudulent issuer 가 token 을 발급하는 상황을 방지** 하는 보안 목적 | [§Security rationale] "By explicitly setting the `hostname` option, we avoid a situation where tokens could be issued by a fraudulent issuer." | `official-vendor-doc` | hostname-strict 정책의 rationale | spoofed `Host` header 로 인한 token issuer 위조 시나리오의 구체적 공격 모델은 본 인용 범위 밖 | | KC-HOST-C4 | `hostname-backchannel-dynamic=true` 설정 시 `hostname` 옵션은 hostname-only 가 아닌 **full URL** 로 지정해야 함 | [§hostname-backchannel-dynamic] "If set to true, `hostname` option needs to be specified as a full URL." | `official-vendor-doc` | frontchannel-backchannel 분리 시나리오 (Keycloak 24+) | full URL 의 정확한 schema/port 처리 (`https://` 의무 여부 등) 는 본 인용 범위 밖 | | KC-HOST-C5 | `hostname-strict` 의 기본값은 `true`. production 에서는 항상 `true` 권장, 단 reverse proxy 가 Host header 를 overwrite 하는 경우만 예외 | [§hostname-strict] "Should always be set to true in production, unless your reverse proxy overwrites the Host header." + [§Relevant options table] `hostname-strict` default: `true` | `official-vendor-doc` | production hardening + reverse proxy 시나리오 | Host header overwrite 의 정확한 동작 (proxy 가 무엇으로 overwrite 하는지) 은 reverse proxy 페이지에서 보강 — `keycloak-reverseproxy-official.md` | ## Usage Boundaries / 적용 경계 - **이 자료가 직접 증명하는 것**: - `KC-HOST-C1` ~ `C5`: hostname 옵션의 보안 rationale, frontchannel/backchannel 분리, hostname-strict 기본값, full URL 요구 조건 - **이 자료가 증명하지 않는 것**: - `iss` claim 생성 시 `KC_HOSTNAME` + realm path 결합 규칙의 정확한 string concatenation (본 페이지에선 명시 없음 — Resource Server 측 검증 동작과 결합) - admin console URL 분리 옵션 (`KC_HOSTNAME_ADMIN`) 의 정확한 동작 - hostname-strict 가 `false` 일 때의 정확한 fallback 동작 (어떤 header / source 를 신뢰) - `KC_HOSTNAME=localhost` 와 backend `issuer-uri=http://keycloak:8080/...` mismatch 의 P3A 시나리오 — 본 페이지의 일반 원칙으로 추론 가능하나 직접 case study 는 없음 - **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: - P3A docker-compose 에서 `network_mode: host` vs `extra_hosts` 어느 쪽이 더 학습 환경에 적합한지 - hostname-backchannel-dynamic 활성 시 OIDC discovery (`.well-known/openid-configuration`) 의 `issuer` 값이 frontchannel vs backchannel 중 어느 쪽으로 표시되는지 - reverse proxy + hostname-strict=true + proxy-headers=xforwarded 조합에서 token `iss` 의 최종 결정 우선순위 ## 핵심 옵션 (페이지 기준 요약) | 옵션 | 의미 | |------|------| | `KC_HOSTNAME` (`--hostname`) | 서버가 노출되는 frontchannel 주소. hostname only 또는 full URL. | | `KC_HOSTNAME_STRICT` (`--hostname-strict`) | 동적 hostname 해석 차단. 기본 `true`. production 의무 (단, reverse proxy 가 Host header 를 overwrite 하는 경우 예외) | | `KC_HOSTNAME_BACKCHANNEL_DYNAMIC` | frontchannel/backchannel URL 분리. true 설정 시 `KC_HOSTNAME` 은 full URL 필수 | | `KC_HOSTNAME_ADMIN` | 관리 콘솔용 별도 hostname (옵션) | ## `iss` claim 과의 관계 (내 프로젝트 해석) > 본 섹션은 자료 직접 인용 아님 — 페이지의 일반 원칙 + Resource Server 측 검증 동작의 결합. wiki 추출 시 별도 처리. - Keycloak 이 발급한 access/ID token 의 `iss` claim 은 `KC_HOSTNAME` (+ realm path) 기반으로 생성. - 예: `KC_HOSTNAME=localhost`, realm `keycloak-patterns` → `iss = http://localhost:8080/realms/keycloak-patterns`. - Resource Server (backend) 는 token 의 `iss` 를 본인이 설정한 `issuer-uri` 와 정확 비교 → 다르면 **검증 실패**. ## P3A 함정 시나리오 (내 프로젝트 해석) > 본 섹션은 자료 직접 인용 아님 — 일반 원칙의 시나리오 적용. wiki 추출 시 별도 처리. 1. docker-compose 에서 keycloak service name `keycloak` 로 두고 backend 가 `issuer-uri=http://keycloak:8080/realms/...` 등록. 2. browser 는 `http://localhost:8080` 에서 로그인 → token `iss = http://localhost:8080/realms/...` (KC_HOSTNAME=localhost 인 경우). 3. backend 는 `http://keycloak:8080/realms/...` 를 기대 → **issuer mismatch → 401**. ### 해결책 (3종) - **A.** `KC_HOSTNAME=localhost` 로 통일 + backend 도 `localhost:8080` 사용 + 컨테이너에서 `network_mode: host` 또는 `extra_hosts: [host.docker.internal:host-gateway]`. - **B.** `KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true` 로 frontchannel/backchannel 분리 (Keycloak 24+ — `KC-HOST-C4`). - **C.** Compose service name 과 외부 hostname 을 동일하게 (Docker DNS alias + `/etc/hosts` 추가). ## P3A/P3B 적용 메모 - 학습 환경에서는 `KC_HOSTNAME=localhost` + `KC_HTTP_ENABLED=true` 로 단순화. - prod 시 hostname-strict 유지 (`KC-HOST-C5`) + HTTPS termination + 정확한 public DNS. ## 한계 / 후속 - 본 문서는 hostname 단일 주제만. realm/client 설정은 별도. - 본 wiki 변환 시 `wiki/concepts/keycloak-iss-claim-and-hostname` 후보. ## Related / 관련 - 같은 주제 다른 official-doc: - [[raw/official-docs/keycloak-reverseproxy-official]] - [[raw/official-docs/keycloak-server-containers-docker]] - [[raw/official-docs/spring-security-resource-server-jwt]] - 인용하는 branch: - [[raw/branch-notes/feature-keycloak-single-ec2-no-google]] - [[raw/branch-notes/feature-keycloak-single-ec2-google-federation]] - [[raw/branch-notes/feature-keycloak-iss-claim-hostname-mismatch]] - 인용하는 wiki: (미작성)