Files
project-infra/docs/adr/0001-keycloak-admin-host-not-public.md
T

3.2 KiB

ADR-0001: Keycloak admin host 는 공개 Ingress 로 노출하지 않는다

  • Status: Accepted
  • Date: 2026-04-24
  • Scope: dev / staging / prod 전 환경

컨텍스트

Keycloak CR 의 spec.hostname.adminhttps://keycloak-admin.dev.example.com 로 선언되어 있다. Keycloak 26 Hostname v2 는 이 값을 admin console 의 베이스 URL 및 redirect 기준으로 사용한다 (공식 문서: https://www.keycloak.org/server/hostname). 그러나 해당 FQDN 에 대응하는 Kubernetes Ingress 리소스는 의도적으로 생성하지 않는다.

결정

  1. keycloak-admin.<env>.example.com 에 대한 공개 Ingress 는 repo 내에 두지 않는다.
  2. admin console 접근은 다음 중 하나를 요구한다:
    • 사내 VPN + kubectl port-forward -n mnt svc/keycloak 9000:9000 (관리 포트 직접 접근)
    • bastion 에서 kubectl execkcadm.sh 호출
    • 향후 별도로 도입할 zero-trust proxy (Pomerium / cloudflared tunnel / Teleport) 경로
  3. spec.hostname.admin 선언 자체는 유지한다 — Keycloak 이 admin UI 링크를 올바른 FQDN 으로 발행해야 외부 OIDC/SAML 메타데이터와 충돌이 없기 때문이다. "FQDN 은 있으나 외부 공개 라우터는 없다" 가 정식 상태다.

근거

  • docs/standards/infra/keycloak.md §11 "Admin Console 은 별도 host 로 분리" + "사내 IP 화이트리스트 / VPN / OIDC forward-auth" 요구와 정합.
  • docs/standards/infra/network-ingress-tls.md §7 "내부 도구(Argo CD, Grafana, Kibana)는 VPN/zero-trust proxy 로만 노출" 및 §16 "/admin/* 는 Ingress path 에 포함하지 않는다" 기준.
  • Keycloak 공식 권장: admin console 의 인터넷 공개는 공격면 확대. sslRequired=external 만으로는 brute-force / credential stuffing / SSRF 경로를 차단하지 못한다.
  • CWE-284 (Improper Access Control) 예방을 위해 관리 평면을 데이터 평면과 물리적으로 분리한다.

결과

  • admin console 접근은 SRE / platform 팀에만 부여되며, 접근 경로는 Runbook (docs/standards/infra/operations-runbook-upgrade-rollback.md) 의 "Keycloak admin 접근" 섹션(TODO)을 따른다.
  • 인증 실패에 대한 alerting 은 /admin/* 공개 환경보다 훨씬 낮은 임계치로 설정 가능 (외부 스캐너 노이즈가 없기 때문).
  • 향후 공개가 필요해지면 이 ADR 의 status 를 Superseded by ADR-XXXX 로 바꾸고 신규 ADR 에서:
    1. keycloak-admin.<env>.example.com 용 Certificate (ECDSA, dev 는 letsencrypt-staging)
    2. 전용 Ingress + Traefik CIDRAllowList middleware (사내 CIDR 만 허용)
    3. oauth2-proxy forward-auth 또는 상호 TLS 인증 중 하나
    4. admin-specific NetworkPolicy (egress-from-keycloak 에 대한 회귀 방지) 를 함께 도입한다.

대안과 기각 사유

  • 대안 A — public Ingress + IP allowlist: Traefik CIDRAllowList middleware 로 사내 CIDR 만 허용. 기각 사유: 사내 CIDR 이 변하거나 원격 근무자 VPN 미사용 시 실수로 통과시키는 위험. 관리 평면은 데이터 평면과 동일 ingress controller 를 공유하지 않는 것이 수비적으로 낫다.
  • 대안 B — Keycloak 내장 IP allowlist: Keycloak 자체 인증 흐름에는 path-level IP 필터 기능이 없다. 기각.