# Keycloak 자체 빌드 — SUSE BCI 기반, 취약 jar 오버레이 포함 # # APP_VERSION 이 곧 Keycloak 릴리스 버전이다. 태그는 # docker.io/paasup/keycloak:--hardened- # 로 만들어진다 (build-hardened-image.sh). DOCKERFILE=suse.Dockerfile TARGET=final TAG_SLUG=bci15.7 APP_VERSION=26.7.1 KEYCLOAK_VERSION=26.7.1 # BCI 는 16.0 이 나와 있지만 15.7 을 쓴다 — 최신이 더 낡았다(2026-08-07 실측). # 15.7 SLE_BCI: java-21-openjdk-headless 21.0.12.0-150600.3.29.1 # 16.0 SLE_BCI: java-21-openjdk-headless 21.0.11.0-160000.2.1 # 21.0.12 가 CVE-2026-41254·CVE-2026-47063 의 수정 버전이라, 16.0 으로 가면 이 이미지의 # 차단 CVE 2건이 오히려 남는다. 필요한 나머지 패키지는 16.0 에도 전부 있으므로 # (glibc-locale-base·ca-certificates-mozilla·sed·grep·findutils·timezone 확인) # **16.0 의 java 가 15.7 을 따라잡으면 그때 올린다.** 재검토 시 위 두 값을 다시 잰다: # docker run --rm registry.suse.com/bci/bci-base:<태그> \ # sh -c 'zypper -n refresh >/dev/null 2>&1; zypper -n info java-21-openjdk-headless' BUILDER_BASE=registry.suse.com/bci/bci-base:15.7 MICRO_BASE=registry.suse.com/bci/bci-micro:15.7 # 업스트림 ubi-null.sh 가 ubi9-micro 위에 남기는 rpm 클로저(44종)의 SUSE 대응물이다. # 근거: quay.io/keycloak/keycloak:26.6.4 SBOM 실측 — bash, coreutils-single, sed, grep, # findutils, glibc-langpack-en, ca-certificates, tzdata, tzdata-java, java-21-openjdk-headless # 가 들어 있고 나머지는 이들의 의존성이다(zypper 가 알아서 끌어온다). # # sed·grep·findutils 는 없으면 안 된다 — bin/kc.sh 가 /bin/sh 스크립트로 esceval() 에서 # sed, 인자 파싱에서 grep 을 쓴다. bci-micro 에는 sed·grep·find 가 **셋 다** 없다 # (2026-08-07 실측 — .claude/image-authoring.md 는 sed 만 기록하고 있었다). # # 패키지명 주의 (2026-08-07 SLE_BCI 15.7 실측) # tzdata → SLE 에는 없다. 이름이 `timezone` 이다. # tzdata-java → SLE 에는 대응 패키지가 없다. Java 는 JDK 내장 tzdb 를 쓴다. # bash·coreutils·ca-certificates-mozilla 는 bci-micro 씨앗에 이미 있다(zypper 가 # "already installed" 로 넘어간다). 무엇이 필요한지 명시하려고 목록에 남겨 둔다. RUNTIME_PACKAGES="java-21-openjdk-headless glibc-locale-base ca-certificates-mozilla bash coreutils sed grep findutils timezone" # 취약 jar 오버레이 대상. 는 keycloak $KEYCLOAK_VERSION 배포본이 실제로 담고 있는 # 버전이고(Quarkus 3.33.2.1 BOM 이 고정), 는 차단 CVE 의 수정 버전이다. # overlay-jars.sh 가 OLD 로 파일을 찾지 못하면 즉시 실패한다 — 업스트림이 버전을 올리면 # 여기가 조용히 무의미해지는 것을 막기 위함이다. # # netty: CVE-2026-55831/55833/56745/56819/59901/55851 (netty-codec-*) # CVE 가 붙은 것만이 아니라 패밀리 전체를 함께 올린다 — netty 는 아티팩트 간 # 버전 혼용이 비지원이다. NETTY_OLD=4.1.135.Final NETTY_VERSION=4.1.136.Final # jackson: CVE-2026-54512/54513 (databind), GHSA-r7wm-3cxj-wff9 (core) # jackson-annotations 는 2.21 로 별도 버저닝이고 CVE 가 없어 건드리지 않는다. JACKSON_OLD=2.21.2 JACKSON_VERSION=2.21.4 # postgresql jdbc: CVE-2026-54291 PGJDBC_OLD=42.7.11 PGJDBC_VERSION=42.7.12 # micrometer: CVE-2026-40983, CVE-2026-40984 (micrometer-core) # netty 와 같은 이유로 패밀리 전체(commons·core·observation·registry-prometheus- # simpleclient)를 함께 올린다. 이 2건은 2026-08-07 로컬 스캔에는 없었고 같은 날 # CI(더 최신 trivy DB)에서 처음 잡혔다 — 로컬 DB 가 뒤처질 수 있다는 실례다. MICROMETER_OLD=1.16.3 MICROMETER_VERSION=1.16.6 BUILD_ARGS="KEYCLOAK_VERSION BUILDER_BASE MICRO_BASE RUNTIME_PACKAGES NETTY_OLD NETTY_VERSION JACKSON_OLD JACKSON_VERSION PGJDBC_OLD PGJDBC_VERSION MICROMETER_OLD MICROMETER_VERSION"