# argocd — 소스 컴파일형 자체 빌드 (유일한 변종) # # build-hardened-image.sh 가 source 한다. BUILD_ARGS 에 나열한 이름만 --build-arg 로 넘어간다. # 소스를 직접 컴파일하므로 "베이스 OS" 선택지가 없다 — BASE_OS=source 로 호출한다: # IMAGE=argocd BASE_OS=source bash scripts/build/build-hardened-image.sh # # 왜 자체 빌드하는가 → source.Dockerfile 상단 주석 / README.md. # argo-cd 10.4.0 CVE 조치(2026-08-19)로 도입 — 근거·경과는 MEMORY.md. # # ── 다음 CVE 조치에서 바뀌는 것은 이 파일뿐이다 ──────────────────────────────── # Dockerfile 에는 버전도 모듈 목록도 박혀 있지 않다. 새 차단 CVE 가 나오면: # Go stdlib CVE → GO_BUILDER_TAG 를 올린다 # Go 모듈 CVE → GO_MODULE_UPGRADES 에 `@` 을 추가한다 # OS 패키지 CVE → RUNTIME_BASE 를 올리거나 RUNTIME_PACKAGES 를 조정한다 # 구성요소 새 릴리스 → 해당 *_VERSION 을 올린다 DOCKERFILE=source.Dockerfile TARGET=final TAG_SLUG=security # build-hardened-image.sh 가 태그·verify.sh 전달용으로 요구하는 범용 필수값. # 스톡 v3.5.1 과는 태그 슬러그(TAG_SLUG=security)로 구분되므로 버전 문자열은 그대로 둔다. APP_VERSION=3.5.1 # v3.5.1 태그가 가리키는 커밋(lightweight 태그라 태그 객체 없이 커밋 직접 참조), 2026-08-19 확인. SOURCE_COMMIT=109ca7ca71139e514114499d294a492e7910a965 # stdlib 차단 CVE 를 해소하는 최소 Go 버전. suggest-go-upgrades.py 가 산출한다. # 빌더 스테이지에만 쓰이고 최종 이미지에는 남지 않는다. GO_BUILDER_TAG=1.26.6-trixie # UI 빌드용. 업스트림 Dockerfile 의 node pin 과 동일하게 맞춘다 — UI 번들은 스캔에서 # 취약점이 잡히지 않으므로 올릴 이유가 없고, lockfile 과의 정합을 지키는 쪽이 안전하다. NODE_BUILDER_TAG=24.14.1 # 최종 런타임 베이스 — 카탈로그는 SUSE BCI 하나만 쓴다(.claude/image-authoring.md 원칙 2). # argocd 는 git/gpg/ssh 런타임이 필요해 패키지 매니저가 있는 bci-base 를 쓴다. # base 와 micro 를 스캔해 비교했고 차이가 없어, micro 씨앗 방식(.claude/image-authoring.md)의 # 복잡도를 감수할 이점이 없었다. # # **16.0 을 쓰는 이유 — coreutils 버전이 차트 요구사항을 가른다.** # argo-cd 차트의 repo-server init 컨테이너(copyutil)가 `cp --update=none` 을 쓴다. 이 # 형식은 GNU coreutils 9.3+ 에서만 되는데 15.7 은 그보다 낮아 # "option '--update' doesn't allow an argument" 로 죽는다(실측 — 15.7 로 빌드해 배포했다가 # repo-server 가 Init:CrashLoopBackOff 로 실패했다). 16.0 은 coreutils 9.6 이라 동작한다. # 16.0 의 패키지 가용성과 trivy 커버리지(CoverageProbe=ok, EOSL 아님)도 확인했다. # verify.sh 가 이 명령을 직접 검사하므로 다음에 베이스를 바꿔도 빌드 단계에서 걸린다. RUNTIME_BASE=registry.suse.com/bci/bci-base:16.0 # 번들 Go 도구 — 업스트림은 hack/install.sh 로 릴리스 바이너리를 내려받지만, 그 바이너리의 # Go 버전이 낡아(git-lfs 1.25.3 · kustomize 1.24.0) CVE 의 주범이었다. 소스에서 다시 만든다. # helm 만 업스트림 pin(4.2.1) 대신 최신을 쓴다 — 나머지 둘은 pin 이 이미 최신이다. HELM_VERSION=4.2.4 KUSTOMIZE_VERSION=5.8.1 GIT_LFS_VERSION=3.7.1 # SLE_BCI 에 패키지가 없어 소스 빌드한다(2026-08-19 zypper 실측). # tini 는 업스트림 ENTRYPOINT, connect-proxy 는 SSH-over-proxy 용이다. TINI_VERSION=0.19.0 SSH_CONNECT_VERSION=1.106 # 강제 업그레이드할 Go 모듈 — argocd·helm·kustomize·git-lfs 네 프로젝트에 **공통 적용**된다. # go-mod-upgrade.sh 가 각 프로젝트의 의존성 그래프에 있는 것만 골라 적용하므로 하나의 # 목록을 그대로 재사용할 수 있다. # # 값은 suggest-go-upgrades.py 로 산출한다. 단, 제안값은 CVE 요건의 **최소치**라 모듈 간 # 제약으로 더 올려야 할 수 있다 — 빌드가 "requires @vX, not @vY" 로 실패하면 그 # 버전으로 올린다(x/crypto 가 이 경우였다). GO_MODULE_UPGRADES="golang.org/x/crypto@v0.53.0 golang.org/x/net@v0.56.0 golang.org/x/text@v0.39.0 google.golang.org/grpc@v1.82.1 github.com/go-git/go-git/v5@v5.19.2 oras.land/oras-go/v2@v2.6.2" # c-builder 가 tini(cmake)·connect(gcc) 를 컴파일하는 데 필요한 것들. BUILDER_PACKAGES="gcc make cmake git-core tar gzip" # 최종 이미지 런타임 패키지 — 업스트림 apt 목록의 SLE 대응(README.md 매핑표 참고). RUNTIME_PACKAGES="git-core ca-certificates gpg2 timezone openssh-clients" BUILD_ARGS="SOURCE_COMMIT APP_VERSION GO_BUILDER_TAG NODE_BUILDER_TAG RUNTIME_BASE HELM_VERSION KUSTOMIZE_VERSION GIT_LFS_VERSION TINI_VERSION SSH_CONNECT_VERSION GO_MODULE_UPGRADES BUILDER_PACKAGES RUNTIME_PACKAGES"