--- 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 / 묶음 - [[wiki/blog/ca-tmpl-devops-ci-supply-chain-dx-2026-07-02]]