Files
llm-wiki/wiki/projects/ca-tmpl/devops-ci-supply-chain-dx.md
T

142 lines
12 KiB
Markdown

---
title: ca-tmpl - DevOps Baseline 결정 (CI + Supply chain + DX)
source_type: project
status: verified
confidence: high
tags: [ca-tmpl, devops, ci-cd, supply-chain, sigstore, actually-implemented, locally-verified]
related_projects: [ca-tmpl]
last_reviewed: 2026-07-02
---
# ca-tmpl - DevOps Baseline 결정 (CI + Supply chain + DX)
> Layer: `wiki/projects/` — 내 프로젝트 사실. 일반 개념은 [[wiki/concepts/devops-ci-supply-chain-dx]] 참조.
## 프로젝트 컨텍스트
ca-tmpl은 ca-skeleton의 운영 가능한 백엔드 템플릿 skeleton이다. **현재 C2 구현 + 로컬 검증 완료.** DevOps baseline은 다음 결정으로 고정되어 있고, GitHub workflow / Gradle gate / supply-chain script 일부가 실제 repository에 존재한다 (canonical §29 G-E + 3개 branch-notes).
- **CI**: GitHub Actions `needs:` + `if: success()` 모델, **Gate ↔ Branch Contract Test 소유권 매트릭스 20행**, flaky test quarantine bucket **14일 sunset**.
- **Supply chain**: **Cosign keyless** (Sigstore Fulcio + Rekor) signing 의무, **SLSA provenance attestation** 의무, **Gradle dependency-locking** (`lockMode = STRICT`), reproducible build.
- **DX**: **`./gradlew bootstrap`** 5단계 단일 진입점, **Temurin 21 LTS** + `.tool-versions` 핀, **Testcontainers** `@ServiceConnection` 기반 integration test, `markdown-link-check`.
이 문서는 결정의 사실 범위와 검증 등급을 분리해 기록한다.
## 실제 구현 내용 (`actually-implemented`)
- `.github/workflows/ci-quality-gates.yml`, `dependency-vulnerability.yml`, `build-release-supply-chain.yml`, `link-check.yml`, `supply-chain-retention-audit.yml`가 존재한다.
- `.github/ci-gate-matrix.yml`, `.github/dependency-review-config.yml`, `.github/supply-chain-policy.json`, `.github/scripts/verify-supply-chain-contract.sh`, `.github/scripts/test-supply-chain-scripts.sh`가 gate/supply-chain 정책을 코드화한다.
- `src/build.gradle``verifyCleanArchitectureDependencies`, `verifyEnvKeys`, `verifyQuarantineSunset`, `verifyTrivyignore`, `verifyReadmeCommands` 등이 check graph에 포함된다.
- module별 `gradle.lockfile`, `.trivyignore.yaml`, `flaky-quarantine.yaml`가 존재한다.
## 로컬/dev 검증 (`locally-verified`)
- `./gradlew check` 통과(2026-07-02, `BUILD SUCCESSFUL`, 114 tasks).
- 실행 중 `verifyCleanArchitectureDependencies`, `verifyEnvKeys`, `verifyQuarantineSunset`, `verifyReadmeCommands`, `verifyTrivyignore`가 OK로 통과했다.
- `DeveloperExperienceContractTest`, `ContractRegistrySchemaGovernanceTest`, `SampleRemovalSmokeContractTest` 등 bootstrap/contract tests가 workflow/gate 파일을 검증한다.
## 운영 검증 (`prod-verified`)
없음. hosted GitHub Actions run, 실제 release publication, Rekor/GHCR/Cosign live verification은 이 문서에서 확인하지 않았다.
## 문서/계획만 존재 (`documented-only` / `planned`)
아래 항목은 구현/로컬 검증된 것과 live release 검증이 필요한 것을 분리한다.
### CI (`actually-implemented` / `locally-verified`)
- **GitHub Actions `needs:` + `if: success()`** 기반 release-blocking gate 모델 결정.
- **Gate ↔ Branch Contract Test 소유권 매트릭스 20행** — 각 gate가 어느 branch contract test에 의해 깨질 수 있는지, 누가 소유하는지 명시 (canonical §29 G-E + [[raw/branch-notes/feature-ci-quality-gates-contract]]).
- **OpenAPI snapshot diff** — springdoc + openapi-diff/oasdiff로 controller 변경 자동 감지. dynamic routing 누락 한계 인지됨.
- **Trivy** image vulnerability scan gate.
- **Flaky test quarantine bucket + 14일 sunset** — Spotify/Google/MS 운영 vs Fowler 반대 절충안.
### Supply chain (`partially-implemented`)
- **Cosign keyless signing** — Fulcio 단명(10분) cert + Rekor transparency log. `--certificate-identity` + `--certificate-oidc-issuer` 검증 정책 필요성 인지됨.
- **SLSA provenance attestation** — in-toto attestation, DSSE envelope, Cosign이 동일 envelope 서명.
- **Gradle dependency-locking** — `dependencyLocking { lockAllConfigurations() }` + `lockMode = STRICT`, `--write-locks`로 lockfile 생성.
- **SemVer + git sha suffix** 버전 정책, reproducible build 목표.
- **Cosign verify identity policy** (`--certificate-identity` + `--certificate-oidc-issuer`) — 2026-05-22 후속 보강 결정. 면접 답변 시 "identity 매칭까지 정책에 명시했다"로 정정 가능. 근거: [[raw/official-docs/cosign-keyless-identity-verification-policy]].
- **SLSA v1.0 provenance schema 필드명 정정 결정 (2026-05-22)** — provenance 생성 시 spec 필드명(`buildDefinition.externalParameters`, `runDetails.builder.id`, `runDetails.metadata.invocationId` 등) 사용, branch-note의 약식 명명(`build.config.source`, `build.invocation`, `materials`)은 forbidden. 근거: [[raw/official-docs/slsa-v1-provenance-schema]].
### DX (`actually-implemented` / `locally-verified`)
- **`./gradlew bootstrap`** 5단계: compileTestJava → docker compose up → Flyway migrate → sample profile seed → smoke.
- **Temurin 21 LTS** + `.tool-versions` (asdf/mise 호환).
- **Testcontainers** `@ServiceConnection` (Spring Boot 3.1+), reuse 옵션은 CI 비활성화.
- **markdown-link-check** dead link 검사.
### 검토한 대안 (5+종)
CI provider (GitLab CI / Jenkins / CircleCI / Tekton), signing (GPG vs Cosign), provenance (in-toto vs ad-hoc), dependency lock (Gradle vs Maven Enforcer), tool versioning (mise/asdf vs SDKMAN), dev environment (Devcontainer 단독 vs bootstrap 병행) — 상세 비교는 [[wiki/concepts/devops-ci-supply-chain-dx]] 참조.
## 면접에서 말할 수 있는 범위
### 자신 있게 답할 수 있는 질문
- CI **Gate ↔ Branch Contract Test 소유권 매트릭스**의 의미 (누가 어떤 gate 실패에 책임지는가).
- **Flaky test quarantine 14일 sunset**의 근거 (Spotify/Google/MS 운영 인정 + Fowler 반대 입장 절충).
- **Cosign keyless vs GPG** 트레이드오프 (단명 cert + Rekor 의존성 추가 vs GPG key 관리 비용 제거).
- **SLSA Build L1/L2/L3** 각 레벨이 보장하는 것과 GitHub Actions hosted runner에서 현실적 도달 범위.
- **Gradle dependency-locking 필요성**과 Maven에 transitive lockfile이 1급 시민으로 없는 이유.
- **Testcontainers vs H2** 선택 이유 (production parity vs 시작 비용).
### 적당히 답할 수 있는 질문
- **Tekton vs GitHub Actions** — k8s 인프라 부담과 skeleton 적합도.
- **in-toto attestation** statement/predicate/DSSE envelope 구조.
### 답하면 안 되는 질문 (모른다고 해야 함)
- "**CI pipeline 운영 경험**" — workflow와 local gate 검증은 가능. hosted CI 운영 이력은 별도 확인 필요.
- "**SLSA L3 달성**" — 약식 매핑 단계, hermetic build 미구성.
- "**Cosign signature 검증 운영 경험**" — 정책/스크립트는 존재하지만 live Rekor/GHCR 검증 이력은 별도 확인 필요.
- "이 skeleton으로 실제 release 한 적 있는가" — 없음.
## 과장 금지 지점
- **"Cosign 서명 누락만 차단하면 안전하다"** → ❌. `--certificate-identity` + `--certificate-oidc-issuer` **identity 매칭 정책**이 없으면 임의 OIDC identity가 만든 서명도 통과된다. 정책 표현 형식은 후속 보강 대상(`needs-confirmation`).
- **"SLSA Build L3를 달성했다"** → ❌. 현재는 **약식 매핑 단계**이며, GitHub Actions hosted runner만으로 L3(hermetic/tamper-resistant builder) 도달 어렵다. 현실 목표는 L2.
- **"SLSA spec 필드명에 정확히 매핑됐다"** → ❌. branch-note의 약식 표현(`build.config.source`, `build.invocation`)은 spec 실제 필드명(`buildDefinition.externalParameters`, `runDetails.builder`, `materials`)과 다르며 **정정 필요**.
- **"Google/Spotify가 quarantine 운영하므로 공식 best practice다"** → ❌. *company-tech-blog* 등급이며 Fowler 반대 입장과 양립한다.
- **"`./gradlew bootstrap` 한 줄이 끝났다 = 정상이다"** → ❌. 5단계 중 어디서 실패했는지 step 단위 exit code 분리가 필요.
- 본 문서는 2026-07-02 코드와 `./gradlew check`로 검증되어 `confidence: high`로 승격했다. 단 live release/supply-chain publication 경험과 혼동하지 않는다.
### Blog-topic ingest: gitea-act-dependency-security-gate-portability (2026-07-02)
[[raw/blog-topics/gitea-act-dependency-security-gate-portability-2026-07-02]] 는 GitHub Actions 전용 dependency-review/trivy-action을 Gitea와 act_runner 환경에서도 다룰 수 있도록 플랫폼 독립 CLI gate로 조정한 이유를 블로그로 풀기 위한 raw seed다.
- **canonical 반영 범위**: dependency vulnerability gate portability 글감을 DevOps/Supply-chain canonical에 연결했다.
- **blogify 전 조건**: 충족. 이 문서는 2026-07-02 기준 코드와 `./gradlew check`로 검증됨.
- **블로그 전 과장 방지**: 모든 CI에서 동작한다고 쓰지 않고, portability를 높인 설계로 제한한다.
- [[raw/blog-topics/five-stage-local-bootstrap-contract-2026-06-24]]: 단일 bootstrap 명령의 가치를 compile/dependency/migration/contract/HTTP smoke 실패를 서로 다른 증거로 분리하는 데 둔 글감. Linux local 검증을 모든 OS/CI/prod 보장으로 표현하지 않는다.
- [[raw/blog-topics/trivy-suppression-governance-static-gate-2026-06-20]]: `.trivyignore.yaml` suppression에 만료일·사유 없는 silent bypass가 생기지 않도록 Gradle 정적 게이트로 강제한 글감. 운영에서 취약점 우회를 막았다고 쓰지 않고 locally-verified gate로 제한한다.
- [[raw/blog-topics/ci-gate-wiring-vs-policy-ownership-2026-06-20]]: release-blocking 여부를 정하는 gate wiring과 scanner/threshold를 정하는 policy ownership을 분리하는 글감. `always()` fan-in과 delegated-pending gate의 실제 차단 검증은 별도 확인 대상이다.
- [[raw/blog-topics/digest-first-java-release-pipeline-2026-06-21]]: reproducible JAR, digest-bound SBOM/Cosign/SLSA 검증, rollback manifest를 하나의 release DAG로 묶는 글감. live OIDC/Rekor/GHCR evidence 전까지 production release 성공으로 쓰지 않는다.
- [[raw/blog-topics/gradle9-java21-static-analysis-baseline-2026-06-20]]: Gradle 9 / Java 21 멀티모듈에 Spotless, Checkstyle, SpotBugs, FindSecBugs, ErrorProne을 도입하며 formatter/linter 책임과 BOM classpath 충돌을 다룬 글감. static analysis baseline을 운영 품질 보장처럼 쓰지 않는다.
## 관련 개념
- [[wiki/concepts/devops-ci-supply-chain-dx]]
## Sources
- [[raw/project-notes/ca-skeleton-operational-contract]] §29 Group G-E — DevOps / CI / Supply chain / DX 대안 조사 인덱스 (canonical SSOT).
- [[raw/branch-notes/feature-ci-quality-gates-contract]] — Gate ↔ Branch Contract Test 소유권 매트릭스 20행, flaky quarantine 14d sunset SSOT, OpenAPI snapshot diff, Trivy.
- [[raw/branch-notes/feature-build-release-supply-chain-contract]] — Cosign keyless 의무, SLSA provenance attestation 의무, Gradle dependency-locking, SemVer + git sha suffix, reproducibility.
- [[raw/branch-notes/feature-dependency-vulnerability-management-contract]] — dependency security gate portability parent branch
- [[raw/blog-topics/gitea-act-dependency-security-gate-portability-2026-07-02]] — Gitea/act dependency security gate portability 블로그 글감 raw seed
- [[raw/branch-notes/feature-developer-experience-contract]] — `./gradlew bootstrap` 5단계, Temurin 21 LTS, Testcontainers integration, markdown-link-check.
- [[raw/blog-topics/five-stage-local-bootstrap-contract-2026-06-24]] — five-stage local bootstrap 블로그 글감 raw seed
- [[raw/blog-topics/trivy-suppression-governance-static-gate-2026-06-20]] — Trivy suppression governance static gate 블로그 글감 raw seed
- [[raw/blog-topics/ci-gate-wiring-vs-policy-ownership-2026-06-20]] — CI gate wiring vs policy ownership 블로그 글감 raw seed
- [[raw/blog-topics/digest-first-java-release-pipeline-2026-06-21]] — digest-first Java release pipeline 블로그 글감 raw seed
- [[raw/blog-topics/gradle9-java21-static-analysis-baseline-2026-06-20]] — Gradle 9 / Java 21 static analysis baseline 블로그 글감 raw seed
## Cluster / 묶음
<!-- GENERATED: derived-blogs:start -->
- [[wiki/blog/ca-tmpl-devops-ci-supply-chain-dx-2026-07-02]]
<!-- GENERATED: derived-blogs:end -->