Files
llm-wiki/raw/branch-notes/feature-dependency-vulnerability-management-contract.md

62 KiB
Raw Permalink Blame History

title, source_type, status, confidence, branch, parent_branch, related_projects, governing_docs, tags, created, target_merge, status_label, id, kind, project, work_item, inherits, refines, overrides, depends_on, contract_packet, contract_packet_sha256
title source_type status confidence branch parent_branch related_projects governing_docs tags created target_merge status_label id kind project work_item inherits refines overrides depends_on contract_packet contract_packet_sha256
branch / feature-dependency-vulnerability-management-contract branch-note raw medium feature-dependency-vulnerability-management-contract
ca-skeleton
raw/project-notes/ca-skeleton-operational-contract
branch
ca-skeleton
security
supply-chain
ci
2026-06-15 in-progress BR-CA-SKELETON-OPERATIONAL-CONTRACT-051 project-work-item ca-skeleton-operational-contract WI-CA-SKELETON-OPERATIONAL-CONTRACT-051
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1
WI-CA-SKELETON-OPERATIONAL-CONTRACT-028
WI-CA-SKELETON-OPERATIONAL-CONTRACT-030
WI-CA-SKELETON-OPERATIONAL-CONTRACT-029
1 bb574e1b56cc247fc24b861ef1249c28991938b0dab6bab63999d5cf9ffb756b

branch: feature-dependency-vulnerability-management-contract

Layer: raw/branch-notes/ — 단일 브랜치의 TODO·결정·진행 기록. 머지/종료 후 verified 결과는 /ingestwiki/projects/에 추출. 원본은 raw에 영구 보관. status_label: in-progress | review | merged | abandoned 계층 표기: "root branch" 라는 별도 개념은 없음. project 의 직접 자식 branch 는 parent_branch:비워두고 related_projects 만 채움. 다른 branch 의 자식이면 parent_branch: <부모 branch 이름> 명시 + ## Parent 섹션의 부모 wikilink 필수.

부모 (필수)

이 branch 가 어느 작업 묶음에 속하는지. 모든 branch 는 예외 없이 upward link 보유.

  • Project 의 직접 자식 branch (parent_branch: 비어있음): raw/project-notes/ca-skeleton-operational-contract
    • 본 branch 는 project-note 의 §18 Control Plane Contract 중 Build / Release / Supply Chain (의존성 취약점 차단) + CI Quality Gates (vulnerability scan gate) 영역을 정제한다.

형제 branch (같은 부모의 다른 자식 — 본 branch 와 계약 경계를 공유):

브랜치 계약 패킷

  • 생성 시 프로젝트 개정: 1
  • 패킷 스키마: contract_packet: 1
  • 완료 조건: scanner·severity·suppression·update·license 정책과 CI failure gate가 명시된다

상속한 프로젝트 결정

Decision Ref Project Summary Branch Application Source
DEC-CA-SKELETON-OPERATIONAL-CONTRACT-STACK-BUILD-001@1 build tool은 Gradle Groovy DSL이다 Work Item 완료 조건에 적용 raw/project-notes/ca-skeleton-operational-contract

브랜치 지역 결정

기존 branch-local 결정은 아래 ## Decision Evidence Map / 결정-근거 매핑의 D-row가 소유하며 이 packet에서 복제하지 않는다.

Decision ID Decision Relation Supporting Claims Status

선언한 예외

Override ID Overrides Reason Approval Status

목표

ca-skeleton 의 §18 Build/Release/Supply Chain 과 CI Quality Gates 에는 "high/critical vulnerability 는 release-blocking" (supply-chain D2) 과 "vulnerability scanner = Trivy + suppression" (ci-gates D5), "dependency upgrade = Renovate/Dependabot" (supply-chain D3) 라는 정책 의도만 있고 외부 근거 없는 UNSUPPORTED_DECISION 스텁이 세 sibling branch 에 흩어져 있다. 어느 branch 도 어떤 스캐너 / 어떤 심각도 표준 / 어떤 임계값 / 어떻게 suppress / 얼마나 빨리 고칠지 를 근거와 함께 정하지 않았다 — 즉 의존성 취약점 관리 정책의 single owner 가 없다.

본 branch 는 그 빈 자리를 메우는 dependency vulnerability 정책 의 single owner 다 (§25 SSOT Owner Map 에 해당 owner 부재 확인 → Cross-Branch Conflict Procedure 통과). 정의 대상: SCA 스캐너 선택, CVSS 심각도 표준·차단 임계값, KEV override, 스캐너 소스 우선순위(tie-break), suppression governance(만료·사유·무단변경 차단), 의존성 보안 업데이트 자동화(Renovate/Dependabot), PR-time 보완 게이트(dependency-review-action). gate wiring 은 ci-gates 가, image scan wiring 은 container-runtime 이, SBOM/서명/locking 은 supply-chain 이 소유하고 — 셋 다 본 branch 의 severity 정책을 consume 한다.

  • 이슈: (미생성 — Phase C2 실 구현 단계에 연결)
  • PR: (미생성)

범위

포함 범위

  • SCA 스캐너 선택 — 의존성(라이브러리) CVE 스캔 도구. ci-gates 의 잠정 "Trivy" 를 공식 근거로 승격/검증.
  • 심각도 분류 표준 + 차단 임계값 — CVSS 버전, 점수→등급 매핑, 어느 등급부터 release-blocking. supply-chain D2 의 "high/critical=blocking" 에 외부 표준 부여.
  • KEV override — 실제 악용(exploited in the wild) CVE 는 CVSS 점수 무관 차단.
  • 스캐너 심각도 소스 우선순위(tie-break) — NVD vs GHSA/벤더 점수 충돌 시 규칙.
  • Suppression governance.trivyignore 포맷 + 만료일 강제 + 사유 기록 + PR 승인 + 무단 변경 차단 정적 게이트(2026-05-25 audit finding 해소).
  • 의존성 보안 업데이트 자동화 — Renovate primary / Dependabot 조건부 + patch-level 보안 PR auto-merge 정책. supply-chain D3 정합.
  • PR-time 보완 게이트 — GitHub dependency-review-action 으로 신규 도입 취약 의존성 차단(전체 스냅샷 스캔과 역할 분리).
  • 스캔 단계/스코프 — PR 게이트 + 의존성 불변이라도 CVE DB 갱신을 잡는 scheduled 재스캔 + pre-release image scan.
  • 의존성 라이선스 준수 스캔(license/NOTICE) — Trivy 가 이미 *gradle.lockfile 의 license 도 스캔(License ✓)하므로 통합. 금지(strong-copyleft) 라이선스 release-blocking + allow-list 정책 + PR-time allow/deny(dependency-review-action). governing §35-E L2052 가 license scan 을 본 branch 영역으로 명시.

제외 범위

의도적으로 제외한 것. 면접 등에서 "이건 범위에 없었습니다"라고 답할 근거.

  • CI gate wiring(release-blocking vs warning-only 판정·needs:/if: 의존성 구성)feature-ci-quality-gates-contract owner. 본 branch 는 정책을 제공만.
  • container image scan wiring + base image 선택feature-container-runtime-contract owner (본 branch severity 정책 consume).
  • SBOM 생성·artifact 서명(Cosign/SLSA)·dependency version locking·artifact versioning·rollbackfeature-build-release-supply-chain-contract owner.
  • secret scan(gitleaks)feature-secrets-config-source-contract owner.
  • 특정 CI provider(GitHub Actions) workflow YAML 의 실제 구현 세부 — 본 branch 는 계약/정책, 구현은 Phase C2.

근거 (필수, 최소 1개+)

이 branch의 구현·설계 결정의 근거가 되는 외부 자료. 공식 문서·대기업 기술 블로그·강의 등 raw 자료를 인용. 같은 자료가 여러 결정의 근거면 결정 표시와 함께 여러 번 등장 가능.

Source 정당화하는 결정
raw/official-docs/trivy-action-github-actions D1/게이트 — exit-code+severity 로 release-blocking CI 게이트 구성, trivyignores 파라미터로 suppression 파일 지정
raw/official-docs/github-dependency-review-action PR-time 보완 게이트 — 신규 도입 취약 의존성 차단(C1·C2). 단독 릴리즈 게이트 부적합(PR diff 전용, C4). severity 커스터마이즈 가능(C3).
raw/official-docs/trivy-filtering-suppression-policy suppression governance — .trivyignore exp:YYYY-MM-DD 만료일(C3), .trivyignore.yaml expired_at 필드(C4) 로 영구 suppress 방지; statement 필드로 사유 기록(C5)
raw/official-docs/vuln-severity-cisa-kev-catalog-official KEV 목록에 등재된 CVE = CVSS 점수와 무관하게 릴리즈 차단(exploitation-in-the-wild override). dueDate 필드 존재는 CISA 자체가 우선 시한을 부여한다는 증거 (CISA-KEV-C3).
raw/official-docs/vuln-severity-cvss-v31-spec-first-official 릴리즈 차단 심각도 기준 = CVSS v3.1 base score, High(≥7.0)/Critical(≥9.0) 차단. FIRST.org 명세가 정성 등급 구간(Table 14, C1)과 Base Score 정의(C3)의 권위 표준.
raw/official-docs/dependabot-security-updates-gradle-official Dependabot 조건부 허용 근거 — security updates 정의(C1), security vs version updates 구분(C2), grouped security updates 생태계 단위 묶음(C3·C4), manifest/lock 한정 트리거(C5)
raw/official-docs/trivy-java-language-coverage D1/SCA 채택 — *gradle.lockfile SBOM·Vulnerability·License 공식 지원(C1), 오프라인 스캔 가능(C2), Java 취약점 소스 = GitHub Advisory Database Maven(C5)
raw/official-docs/renovate-vulnerability-alerts-gradle-official Renovate primary 채택 근거 — security:only-security-updates preset이 osvVulnerabilityAlerts: true + vulnerabilityAlerts.enabled: true + 전체 패키지 기본 비활성화 구성임을 공식 문서로 확인 (C1·C2·C3)

Deferred 아카이브 (후속 /branch-spec 재실행 또는 수동 dispatch) — 아래 자료는 대안 비교·보강 신호 근거로 wiki-decision-researcher 가 URL·핵심 사실을 이미 확보했으나, 본 run 의 archive 예산을 핵심 7건에 집중하느라 raw 미등록. 해당 결정의 Evidence Strength 가 그만큼 낮음을 Decision Evidence Map 에 표기:

  • https://dependency-check.github.io/DependencyCheck/dependency-check-gradle/index.html — OWASP Dependency-Check (D1 대안: 멀티모듈 dependencyCheckAggregate + failBuildOnCVSS, NVD API 키 필요)
  • https://github.com/anchore/grype — Grype (D1 대안: false-positive 최저 + KEV/EPSS 내장, 단 gradle.lockfile 공식 지원 불명확)
  • https://nvd.nist.gov/vuln-metrics/cvss — NVD severity bands (D2 보강: CVSS v3.x/v4.0 밴드 corroboration)
  • https://www.first.org/epss/ — FIRST EPSS (D8 보강: EPSS ≥ 0.1 escalation 신호 근거)
  • https://trivy.dev/docs/latest/scanner/vulnerability/ — Trivy 소스 우선순위(언어 패키지 GHSA>NVD) (D4 보강 — coverage 페이지엔 OS 패키지만 명시됨)
  • https://www.cisa.gov/news-events/directives/bod-26-04-prioritizing-security-updates-based-risk — CISA BOD 26-04 (D3 보강: KEV=독립 우선순위 인자; CISA HTML 403 으로 본 run 미확보)

TODO

각 항목 옆에 증거 등급 표기: actually-implemented | locally-verified | prod-verified | documented-only | planned | needs-confirmation

ca-tmpl ground truth(2026-06-15 확인): .github/workflows/ 없음, gradle/locks/ 없음, Renovate/Dependabot/Trivy config 없음 → 본 branch 전 항목 planned (코드 미존재). actually-implemented 승급은 Phase C2 실 구현 + src//CI grep 확인 후.

  • Trivy fs scan CI job (aquasecurity/trivy-action, scan-type: fs, exit-code: 1, severity: CRITICAL,HIGH, TRIVY_FILE_PATTERNS 멀티모듈 workaround) — 등급: actually-implemented (.github/workflows/dependency-vulnerability.yml trivy-fs 잡, YAML valid; 실제 CI 실행은 needs-confirmation) (D1)
  • dependency-review-action required check (fail-on-severity: high) — 등급: actually-implemented (.github/dependency-review-config.yml + workflow dependency-review 잡; graph 제출은 dependency-submission 잡으로 보강) (D7)
  • severity 정책 문서화: CVSS v3.1 밴드 + ≥High 차단 + KEV override + EPSS escalation — 등급: actually-implemented (.github/dependency-vulnerability-policy.md §2/§3/§4, 모든 team-policy 값 UNSUPPORTED_IMPL_DECISION 라벨) (D2/D3/D8)
  • .trivyignore.yaml suppression 정책 + 만료일 강제 + 무단변경 차단 정적 게이트 — 등급: locally-verified (verifyTrivyignore Gradle gate: 6-케이스 pass/fail 검증 + ./gradlew check green; .trivyignore.yaml 빈 seed + .github/CODEOWNERS merge-gate) (D5)
  • Renovate security:only-security-updates 설정 + patch 보안 PR auto-merge 정책 — 등급: actually-implemented (renovate.json, JSON valid; Renovate 봇 실행은 needs-confirmation) (D6)
  • scheduled 재스캔 job(CVE DB 갱신 캡처) + pre-release trivy image scan — 등급: actually-implemented (workflow schedule daily cron + trivy-image release 잡, vars.RELEASE_IMAGE_REF 게이팅으로 container-runtime wiring seam) (D1/구현가이드 §1)
  • 의존성 라이선스 스캔: Trivy license(gradle.lockfile) + dependency-review-action deny-licenses + 금지 SPDX 목록 정의 — 등급: actually-implemented (scanners: vuln,license + GPL/AGPL deny-list; 목록은 UNSUPPORTED_IMPL_DECISION team-policy) (D10)
  • sibling 역참조 정합: supply-chain D2/D3, ci-gates D5 의 UNSUPPORTED/OWNER_AMBIGUITY → 본 branch 위임으로 갱신 (§Audit & Findings, 비차단) — 등급: planned (비차단 — 다음 작업자//sync; 본 구현 머지와 독립)

진행 중 메모

작업하며 떠오른 메모. 자유 형식.

2026-06-20 — Phase C2 구현 (ca-tmpl, branch feature/dependency-vulnerability-management-contract)

정책 7건(D1·D2/D3/D8·D5·D6·D7·D10·§1)을 ca-tmpl 의 커밋 가능한 아티팩트로 실 구현. 커밋은 사용자가 직접 수행(working tree 만 변경).

커밋 대상 파일 (tracked):

  • .github/workflows/dependency-vulnerability.yml — D1 trivy-fs(PR+daily schedule, scanners: vuln,license, severity: CRITICAL,HIGH, exit-code:1, trivyignores: .trivyignore.yaml, TRIVY_FILE_PATTERNS) + D7 dependency-review(PR) + dependency-submission(gradle/actions/dependency-submission, graph fail-open 보강) + §1 trivy-image(release, vars.RELEASE_IMAGE_REF 게이팅 — container-runtime wiring seam).
  • .github/dependency-review-config.yml — D7 fail-on-severity: high + fail-on-scopes: [runtime] + D10 deny-licenses(GPL/AGPL family) + comment-summary-in-pr: on-failure.
  • .trivyignore.yaml — D5 빈 seed(vulnerabilities/licenses/misconfigurations/secrets: []) + 헤더에 id/statement/expired_at 포맷 문서화. repo 루트(Trivy 자동 인식).
  • renovate.json — D6 config:recommended + security:only-security-updates + vulnerabilityAlerts(stable) + osvVulnerabilityAlerts(experimental) + patch auto-merge / minor·major human review packageRules.
  • .github/CODEOWNERS — D5 §3 ② merge-time 승인(.trivyignore.yaml·policy·workflows·renovate.json@DongHyeonka placeholder).
  • .github/dependency-vulnerability-policy.md — D2/D3/D4/D8/D9/D10 통합 정책 SSOT(committed). 모든 team-policy 수치 UNSUPPORTED_IMPL_DECISION 라벨.
  • src/build.gradle — D5 §3 ① verifyTrivyignore Gradle gate(line-based parser, maxWindowDays=90), subprojects { check { dependsOn } } 배선(기존 verifyEnvKeys 패턴).
  • src/README.md·README.md — gate 문서화 + 정책 참조.

검증(locally-verified): verifyTrivyignore 6-케이스 — 빈 seed pass / 유효+nested paths pass / expired_at 누락 fail / statement 누락 fail / 이미 만료 fail / 90일 초과 fail, seed 복원 후 재pass. ./gradlew check = BUILD SUCCESSFUL(106 tasks). 4개 check-wired gate 동시 통과. workflow/dep-review YAML + renovate JSON 구문 유효성 확인. CI 러너에서의 실제 스캔 동작은 needs-confirmation(§Claims To Verify 참조).

UNSUPPORTED_IMPL_DECISION 기본값 선택(스켈레톤 default, fork 가 교체): scheduled=daily(0 6 * * *); 차단=≥High; EPSS=0.1(비차단); suppression 창=90일; patch auto-merge; license=deny-list(GPL/AGPL, LGPL 허용); SLA=KEV/Critical 7d·High 30d·Medium 90d. verifyPublicPathSnapshot 의 문서화 방식과 동일.

경계 준수: dependencyLocking/lockfile 생성 미추가(supply-chain D8 owner) — Trivy fs 는 lockfile 커밋 전까지 Gradle deps no-op, 그 사이 dependency-submission graph 가 transitive backstop. image scan wiringvars.RELEASE_IMAGE_REF seam 으로 container-runtime 에 위임. CI gate needs:/if: 배선은 ci-gates owner(본 파일은 정책만).

2026-06-20 — 코드 리뷰 수정 2건 (workflow correctness)

  • TRIVY_EXIT_CODE 주석 오기 정정 (correctness): trivy-fs 잡의 TRIVY_EXIT_CODE: "1"exit-code: "1" 입력과 동일 knob(취약점 발견 시 종료코드)이라 중복이었고, 주석이 이를 "DB fetch 실패 시 fail" 메커니즘으로 오기했다. 제거하고, DB-fetch 실패→fail 은 Trivy 기본 동작(캐시 없으면 DB 다운로드 실패 시 non-zero)이며 설정 플래그가 아님 + 여전히 needs-confirmation 임을 정직하게 주석화. §Claims To Verify "스캐너 DB fetch 실패가 silent pass 가 아니라 job fail" 은 여전히 미검증(planned) — 이전 주석이 충족을 거짓 주장했던 것을 철회. 실검증: CI 에서 DB endpoint 차단 후 non-zero exit 단언.
  • Medium "warn/advisory" 티어 실현: policy §2 표는 Medium=warn(advisory)/Low=report 인데 두 Trivy 잡이 severity: CRITICAL,HIGH 만 스캔해 Medium/Low 를 보고조차 안 했음(정책-구현 gap). trivy-fs 에 비차단 advisory step(severity: MEDIUM,LOW, exit-code: "0") 추가로 보고만 하고 차단 안 하는 티어 실현. policy §2 운영 구현 줄도 정합.
  • D3 KEV override 실효 강제 (실효 강제 0 → 실제 차단): severity 필터가 CRITICAL,HIGH 라 §2 matrix 의 "KEV 등재 시 모든 밴드 block" 의도가 Low/Medium 에서 미실현이었음(실효 강제 0). trivy-fs 에 (1) 전체 밴드 JSON 스캔(severity: CRITICAL,HIGH,MEDIUM,LOW,UNKNOWN, exit-code:0, format: json) + (2) KEV override gate run step(CISA KEV JSON feed curl -fsSL --retry 3jq/comm 으로 발견 CVE ∩ KEV → 교집합 있으면 exit 1) 추가. suppression(.trivyignore.yaml)은 그대로 적용 → KEV CVE 는 거버넌스된 suppression 으로만 수용. feed 미가용 = curl -f fail-closed(silent pass 금지, §Edge·Failure JSON feed 가용성 충족). policy §3 을 posture→실효 강제로 갱신. Open Risk(유지): KEV 등재 지연, feed CI 의존.
  • 검증: workflow YAML 재유효성 OK; TRIVY_EXIT_CODE 제거 + advisory/KEV step 존재 grep 확인; KEV cross-check 로직 mock 3-케이스 검증 — KEV 등재 CVE 발견 시 exit1(block), 빈 발견셋(lockfile 부재) pass, 비-KEV CVE pass. (Java/Gradle 코드·게이트 로직 무변경이라 ./gradlew check 재실행 불요. CI 러너 실제 동작은 needs-confirmation.)

2026-06-20 — Gitea/act 플랫폼 적응 (CI 실패 1건 해소)

사용자가 commit cb12207 push 후 self-hosted Gitea + act_runner(k8s 내부, gitea-http.platform.svc.cluster.local)에서 워크플로 실행 → 2개 잡 실패. 타깃 플랫폼 = Gitea 확정.

  • dependency-review 실패 (원인 확정): ::error::Dependency review could not obtain dependency data.... dependency-review-action 은 GitHub Dependency Graph compare API(GitHub.com/GHES 전용)에 의존 → Gitea 에 API 부재 + dependency-submission(graph 제출, push-only)이 PR 이벤트라 skip 돼 graph 도 비어있음. 수정: dependency-review·dependency-submission 두 잡에 && github.server_url == 'https://github.com' 가드 추가 → Gitea 에선 skip(실패 아님), GitHub.com 에선 그대로 동작. Gitea 의 PR-time 의존성 검사는 플랫폼 독립적 trivy-fs(매 PR)가 커버(D7 단독 게이트 금지 설계가 backstop 제공). policy §8 에 플랫폼 호환성 note 추가.
  • trivy-fs 실패 (원인 확정 — egress 가설 철회): trivy-fs step 로그 입수 → git clone 'https://github.com/aquasecurity/trivy-action' # ref=0.28.0Unable to resolve 0.28.0: reference not found. egress 문제 아님(러너가 actions/checkout·trivy-action 을 github.com 에서 정상 clone — github.com·ghcr 접근 가능). 진짜 원인은 액션 태그 오타: aquasecurity/trivy-action 의 실제 태그는 v 접두사(v0.28.0)인데 @0.28.0(v 없이)로 핀해 404. GitHub API 로 실제 태그 확인(tags/0.28.0=404, tags/v0.28.0=200; 최신 v0.36.0). 수정: 워크플로 4곳 @0.28.0@v0.28.0(replace_all). 내 1차 "egress 차단" 진단은 4s 빠른 실패만 보고 세운 가설이었고 로그가 반증 — 증거 우선 위반 사례.
  • skip 정상: dependency-submission(push-only)·trivy-image(release-only)는 PR 이벤트라 의도된 skip(회색).
  • 검증: workflow YAML 재유효성 OK, server_url 가드 2건 + trivy-action @v0.28.0 4건 grep 확인, GitHub API 로 v0.28.0 존재 확인. (YAML 변경만 — ./gradlew 무관.) 재실행 후 trivy-fs 완전 통과(Trivy DB pull + KEV step cisa.gov curl 포함)는 needs-confirmation.
  • trivy-fs 2차 실패 → CLI 전환 (act 의 trivy-action 미지원): 태그 수정 후 재실행하니 액션 resolve 는 통과했으나 entrypoint.sh: line 44: trivy: command not found. aquasecurity/trivy-action 은 setup-trivy 서브액션 + DB 캐시로 Trivy 를 설치하는 composite 인데 act 가 그 설치 스텝을 안 돌려 바이너리 부재. 수정: trivy-action 폐기 → Trivy + jq CLI 정적 바이너리를 github.com 에서 직접 설치(trivy v0.71.2, jq 1.8.1, API 로 태그/자산명 사전 확인) 후 trivy fs/trivy image CLI 직접 호출. --file-patterns 제거(**/*.lockfile 는 CLI 에서 invalid regex 위험 + 표준 gradle.lockfile 명명은 Trivy 기본 탐지로 충분; 비표준 명명만 Claims To Verify). KEV step 에 KEV_FEED_URL repo-var override(폐쇄망 미러) + fetch 실패 시 명시적 fail-closed 메시지 추가. CLI 는 GitHub.com·Gitea/act 공통.
  • skip 정상: dependency-submission(push-only)·trivy-image(release-only)는 PR 이벤트라 의도된 skip(회색).
  • 검증: workflow YAML 재유효성 OK(CLI 전환 후); uses: aquasecurity/trivy-action 제거(주석만 잔존) + trivy fs/trivy image CLI step grep 확인; GitHub API 로 trivy v0.71.2·jq-1.8.1 자산 존재 확인; KEV jq/comm 로직 mock 3-케이스 재확인. (YAML 변경만 — ./gradlew 무관.) 남은 egress 의존(재실행 시 다음 관문): github.com=확인됨, ghcr.io(Trivy DB)·KEV feed 호스트=needs-confirmation(폐쇄망이면 TRIVY_DB_REPOSITORY/KEV_FEED_URL 미러).
  • 파생: raw/errors/gitea-act-action-tag-and-dependency-graph-2026-06-20 (CI 실패 근본원인 + 수정, 2-iteration).

결정 사항

추후 면접/회고에서 "왜 이렇게 했나" 답할 근거. 대안과 함께 기록. 각 결정의 근거는 위 Sources 또는 새로 추가된 raw 자료를 가리킬 것. 상세 매핑은 아래 Decision Evidence Map.

  • 2026-06-15: SCA 스캐너 = Trivy (fs 의존성 + image 동일 바이너리, aquasecurity/trivy-action). 이유: OSS(Apache 2.0) + gradle.lockfile 공식 지원 + NVD API 키 불필요 + image 동일 도구 + exit-code/severity 로 release-blocking 즉시 구성. 검토한 대안: OWASP Dependency-Check(멀티모듈 aggregate 성숙하나 NVD 키 필요), Grype(FP 최저·KEV/EPSS 내장하나 gradle.lockfile 지원 불명확), Snyk(상용 — OSS 스켈레톤 부적합 제외), dependency-review-action(PR 보완 전용). 근거: raw/official-docs/trivy-java-language-coverage, raw/official-docs/trivy-action-github-actions. (ci-gates D5 의 OWNER_AMBIGUITY/미결 해소 — D1)
  • 2026-06-15: 차단 심각도 = CVSS v3.1 base score, High(≥7.0)·Critical(≥9.0) 차단, Medium/Low 는 warning-only. 이유: 스캐너·NVD 커버리지 완전 + FIRST.org 권위 표준 밴드 + industry de-facto 임계값. 검토한 대안: CVSS v4.0(스캐너 미성숙 — 2026-12 재평가). 근거: raw/official-docs/vuln-severity-cvss-v31-spec-first-official. (supply-chain D2 에 외부 표준 부여 — D2)
  • 2026-06-15: KEV override — CISA KEV 등재 CVE 는 CVSS 점수 무관 차단. 이유: exploited-in-the-wild 는 점수보다 실위험이 큼(CISA dueDate 부여). 근거: raw/official-docs/vuln-severity-cisa-kev-catalog-official. (D3)
  • 2026-06-15: Suppression governance.trivyignore(.yaml) + 만료일 강제 + statement 사유 + PR 승인 + 무단변경 차단 정적 게이트. 이유: 만료 없는 영구 ignore 차단(2026-05-25 ca-tmpl audit finding 해소). 근거: raw/official-docs/trivy-filtering-suppression-policy. (D5)
  • 2026-06-15: 의존성 보안 업데이트 = Renovate primary / Dependabot 조건부. 이유: version-catalog+lockfile 동시 사용 시 Dependabot lockfile 미갱신 버그(#12557)가 supply-chain D8 locking 과 충돌; Renovate 는 security-only preset + patch auto-merge 단순. 검토한 대안: Dependabot(조직 표준/단순 구조 시 허용). 근거: raw/official-docs/renovate-vulnerability-alerts-gradle-official, raw/official-docs/dependabot-security-updates-gradle-official. (supply-chain D3 정합 — D6)
  • 2026-06-15: PR-time 보완 게이트 = dependency-review-action (fail-on-severity: high, required). 단독 릴리즈 게이트 금지(PR diff 전용). 근거: raw/official-docs/github-dependency-review-action. (D7)
  • 2026-06-15: 의존성 라이선스 준수 스캔 = Trivy license(이미 toolchain) + dependency-review-action allow/deny. 이유: D1 Trivy 가 *gradle.lockfile license 도 스캔하므로 별도 도구 불필요; governing §35-E L2052 가 license scan 을 본 branch 영역으로 명시. 근거: raw/official-docs/trivy-java-language-coverage, raw/official-docs/github-dependency-review-action. (D10)

결정-근거 매핑

각 결정이 어떤 raw source claim 으로 뒷받침되는지 명시한다. Decision ID 는 이 branch-note 안에서 안정적으로 유지한다. 예: D1, D2. Supporting Claimsraw/<category>/<slug>.md#C1 형식으로 연결한다.

선택 조건 열(R2): "이 조건일 때 이 결정, 다른 조건이면 어떤 대안". 분기 없으면 N/A.

Decision ID Decision 선택 조건 (언제 이 결정 / 언제 대안) Supporting Claims Evidence Strength Open Risk
D1 SCA 스캐너 = Trivy (fs 의존성 스캔 + image 동일 바이너리, aquasecurity/trivy-action, exit-code:1+severity:CRITICAL,HIGH=release-blocking) OSS + NVD 키 불필요 + gradle.lockfile 지원 + image 동일 도구 → Trivy. 멀티모듈 dependencyCheckAggregate 공식 지원 + CVSS 소수점 임계값 제어가 더 중요 → OWASP Dependency-Check (NVD API 키+캐싱 감수). FP 최저+EPSS/KEV 내장이 최우선 → Grype(단 gradle.lockfile POC 선행) raw/official-docs/trivy-java-language-coverage.md#C1 (*gradle.lockfile SBOM/Vuln/License ✓), raw/official-docs/trivy-java-language-coverage.md#C2 (오프라인 스캔), raw/official-docs/trivy-action-github-actions.md#C1·#C2 (exit-code/severity release-blocking), raw/official-docs/trivy-action-github-actions.md#C4 (trivyignores) official-vendor-doc (Aqua Trivy) — 대안(OWASP DC/Grype/Snyk) 비교는 §Sources Deferred 아카이브 멀티모듈 lockfile 탐지 버그 → --file-patterns "gradle-lockfile:*.lockfile" workaround(공식 문서 미명시, Claims To Verify); Gradle force=true 재정의 false positive; lockfile 생성이 선행조건raw/branch-notes/feature-build-release-supply-chain-contract D8(dependency-locking) 의존
D2 차단 심각도 = CVSS v3.1 base score; High(≥7.0)·Critical(≥9.0)=release-blocking, Medium(4.06.9)/Low(0.13.9)=warning-only(비차단 advisory) 스캐너 지원·NVD 커버리지 완전 → v3.1. 스캐너 v4.0 파싱 안정 + NVD/Vulnrichment v4.0 커버리지 확보 후 → v4.0(밴드 수치 동일, 2026-12 재평가) raw/official-docs/vuln-severity-cvss-v31-spec-first-official.md#C1 (Table 14 밴드 None/Low/Medium/High/Critical), raw/official-docs/vuln-severity-cvss-v31-spec-first-official.md#C2 (정성 등급=조직 vuln mgmt 프로세스 입력), #C3 (base score=intrinsic) official-standard (FIRST.org) — 단 밴드만 표준; "≥High 차단" 임계값 선택은 industry de-facto(team-policy) "≥High 차단"의 industry de-facto 근거 미아카이브 → UNSUPPORTED_IMPL_DECISION(§구현가이드 §2); v3.1 Scope metric 불일치 알려짐; NVD enrichment 정책 변경(2026-04) → 신규 CVE CVSS 공백 가능(Claims To Verify)
D3 KEV override — CISA KEV catalog 등재 CVE = CVSS 점수 무관 release-blocking N/A (항상 적용 — exploited-in-the-wild 가 점수보다 우선) raw/official-docs/vuln-severity-cisa-kev-catalog-official.md#CISA-KEV-C1 (catalog 존재), #CISA-KEV-C3 (dueDate=CISA 우선 시한 부여), #CISA-KEV-C4 (ransomware 연관 식별) official-vendor-doc (CISA JSON feed) — "exploited in the wild" 정의·비연방 권고·BOD 26-04 4-factor 는 CISA HTML 403 으로 미확보(needs-confirmation, Deferred) KEV 등재 지연(악용→catalog entry 간격); JSON feed 가용성 CI 의존; BOD rationale 미아카이브
D4 소스 우선순위 tie-break: Java/Gradle 의존성 → GitHub Advisory Database(GHSA) 우선 → NVD fallback NVD 와 GHSA/벤더 점수 충돌 시 GHSA 우선(Trivy 기본). KEV 등재면 tie-break 무관 차단(D3) raw/official-docs/trivy-java-language-coverage.md#C5 (Java 취약점 소스 = GitHub Advisory Database (Maven)) official-vendor-doc (부분) — GHSA 를 소스로 씀 만 확인; 충돌 시 GHSA 가 NVD override 명시는 coverage 페이지에 없음(OS 패키지만 명시) → 부분 UNSUPPORTED_DECISION language-package vendor>NVD 우선순위 verbatim 미확보 → Trivy scanner/vulnerability 페이지 보강 필요(Deferred + Claims To Verify)
D5 Suppression governance.trivyignore/.trivyignore.yaml + 만료일 필수(exp:YYYY-MM-DD/expired_at) + statement 사유 + PR review approval + 무단 .trivyignore 변경 차단 정적 CI 게이트 false-positive/accepted-risk suppress 필요 시 — 만료 없는 영구 ignore 금지 raw/official-docs/trivy-filtering-suppression-policy.md#C1 (CVE 한 줄+만료 지원), #C3 (exp:YYYY-MM-DD), #C4 (expired_at, 미지정시 영구유효), #C5 (statement=사유 기록) official-vendor-doc (Trivy filtering) 만료 기간 길이(예: 90d)·PR 승인 권한(CODEOWNERS)·무단변경 차단 게이트 구현(regex)은 team-policy → UNSUPPORTED_IMPL_DECISION(§구현가이드 §3). 2026-05-25 ca-tmpl audit .trivyignore 무단 우회 finding 해소 대상
D6 의존성 보안 업데이트 = Renovate primary (security:only-security-updates preset → vulnerabilityAlerts+osvVulnerabilityAlerts), Dependabot 조건부 gradle/libs.versions.toml version catalog + Gradle lockfile 동시 사용 → Renovate (Dependabot #12557 lockfile 미갱신 버그가 supply-chain D8 locking 과 충돌). 조직이 Dependabot 표준 또는 lockfile 미사용 단순 구조 → Dependabot 허용 raw/official-docs/renovate-vulnerability-alerts-gradle-official.md#C1·#C2 (security:only-security-updates→osv+vulnerabilityAlerts), raw/official-docs/dependabot-security-updates-gradle-official.md#C1 (security updates 정의), #C2 (security vs version 구분), #C3 (grouped per-ecosystem), #C5 (manifest/lock 한정 트리거) official-vendor-doc (Renovate + GitHub) Renovate osvVulnerabilityAlerts experimental 상태 + vuln-alert schedule-ignore 는 presets 페이지 미확인(needs-confirmation); Dependabot Gradle 지원·#12557·native auto-merge 부재는 researcher finding(이 페이지 미확인); transitive 취약점은 둘 다 직접 의존성만 → Gradle dependency constraint 수동 override 필요(§구현가이드 §4)
D7 PR-time 보완 게이트 = GitHub dependency-review-action (fail-on-severity: high, required check) 모든 PR(feature + 보안 PR). 단독 릴리즈 게이트 금지 — PR diff 전용이라 기존 의존성 전수 스캔 못함, 그건 D1 Trivy fs raw/official-docs/github-dependency-review-action.md#C1 (catch before introduce), #C2 (PR 도입 취약 버전 스캔), #C3 (default fail + required 시 merge block), #C4 (REST API base..head diff), #C5 (severity 커스터마이즈) official-vendor-doc (GitHub) Gradle dependency graph 가 GitHub 에 제출돼야 diff 유의미(Claims To Verify); fail-on-severity 정확 값은 별도 config 페이지(needs-confirmation, Deferred)
D8 EPSS escalation signal (optional, 비차단) — EPSS ≥ 0.1 인 Low/Medium CVE → 즉시 review ticket(P1). 하드 차단 아님 D2 에서 비차단(Low/Medium)인데 EPSS≥0.1 → escalate. High/Critical 은 이미 D2 차단 UNSUPPORTED_DECISION — FIRST EPSS 페이지 미아카이브(Deferred); 0.1 임계값은 FIRST top-decile practitioner 합의일 뿐 공식 차단 mandate 없음 team-policy (외부 reference: FIRST EPSS, deferred) EPSS=확률 추정 → false positive; 0.1 임계값=조직 정책; 본 결정 자체 optional(미도입 가능)
D9 Remediation SLA by severity — KEV/Critical: 즉시(≤Xd), High: ≤Yd, Medium: ≤Zd 차단/escalation 된 취약점 수정 기한 UNSUPPORTED_DECISION — 비-KEV SLA 수치는 외부 표준 부재(team-policy). KEV 항목만 raw/official-docs/vuln-severity-cisa-kev-catalog-official.md#CISA-KEV-C3 (dueDate) 외부 anchor team-policy (+ KEV 항목 official-vendor-doc anchor) 정량 일수(X/Y/Z)는 조직 결정 — 임의 trade-off 제시 시 UNSUPPORTED_IMPL_DECISION
D10 의존성 라이선스 준수 스캔(license/NOTICE) = Trivy license scanner(이미 toolchain) + dependency-review-action allow/deny license list. 금지(strong-copyleft) 라이선스 = release-blocking, allow-list 정책 Trivy 가 이미 D1 로 채택됐고 *gradle.lockfile license 스캔 → 별도 license 도구 불필요(통합). PR-time 신규 라이선스 도입 차단은 dependency-review-action allow/deny raw/official-docs/trivy-java-language-coverage.md#C1 (gradle.lockfile License ✓), raw/official-docs/github-dependency-review-action.md#C6 (allow/deny list for licenses) official-vendor-doc (Trivy + GitHub) 금지/허용 SPDX 라이선스 목록(어떤 id 가 release-blocking 인지)은 조직 정책 → UNSUPPORTED_IMPL_DECISION(§구현가이드 §5); Trivy license 감지는 Gradle cache 디렉터리($GRADLE_USER_HOME/caches) 의존(trivy-java-language-coverage 메모 — dependency-tree EXPERIMENTAL) → Claims To Verify

구현 가이드

결정 (Decisions) 이 "무엇 을 할 것인가" 라면, 본 §는 "어디에 어떻게 구현될 것인가" 의 사전 명세 — 문서가 모호해서 구현자가 임의로 정해야 했던 결정 카탈로그. 작성 목표는 다음 구현자가 되묻지 않아도 코드를 작성할 수 있는 수준.

본 §는 일률적 anchor list 를 강제하지 않는다. branch 마다 구현 내용·범위가 다르므로 sub-section 은 이 branch 의 결정과 근거에서 도출되는 것만 작성. 어떤 branch 는 error mapping 표 + 정적 강제 카탈로그, 어떤 branch 는 migration 단계 + wiring, 어떤 branch 는 sequence + state machine. 형식 예시는 raw/branch-notes/feature-boundary-validation-mapping-contract 의 §구현 가이드 참조.

3-rule meta principle (필수 준수):

  1. R1. Reference 필수 — 각 sub-section / row / cell 은 본 branch 의 Decision ID (예: D1, D2) + 그 결정의 Supporting Claim ID (예: RAW-SLUG-C1) 를 reference. 근거 없는 결정 금지 — 모든 구현 detail 은 결정 + 근거의 도출 이어야 함.
  2. R2. UNSUPPORTED_IMPL_DECISION 명시 — 근거 raw 가 원칙 만 권고하고 detail (메커니즘 선택 / 클래스/rule 명명 / glob 패턴 / algorithm / factory API 모양 등) 은 권고하지 않는 cell 은 UNSUPPORTED_IMPL_DECISION 라벨 + 사용자 trade-off 근거 한 줄. 이게 근거 있는 결정 vs 사용자 임의 trade-off 의 경계.
  3. R3. OUT_OF_BRANCH_SCOPE 정제 — 본 branch 결정 범위 밖 cell 은 §구현 가이드에 남기지 않음. 별도 branch 또는 canonical SSOT 로 이관 (이관 history 는 별도 § "Audit & Findings" 등에 보존). 도메인 특화 detail (ca-tmpl skeleton 범위 밖) 도 동일하게 정제.

각 sub-section 의 권장 헤더 패턴:

### N. <sub-section 제목>

> **Trace**: <In-scope row 들 + Decision ID + Supporting Claim ID 의 매핑 (한 줄/한 단락)>
>
> - **UNSUPPORTED_IMPL_DECISION**: <근거 없는 사용자 임의 결정 항목들 + 각각의 trade-off 근거 한 줄>

<표 또는 명확한 구조 — 자유 텍스트 = 모호함 = 되묻기 원인>

1. 스캔 배선 — 단계별 스캐너 실행 (3-stage)

Trace: D1 (trivy-java-language-coverage#C1·#C2, trivy-action-github-actions#C1·#C2·#C3), D7 (github-dependency-review-action#C2·#C3). gate 의 release-blocking 배선(needs:/if:) 자체는 raw/branch-notes/feature-ci-quality-gates-contract owner — 본 §는 무엇을 어느 단계에서 스캔하는지 만 정의하고 ci-gates 가 wiring.

  • UNSUPPORTED_IMPL_DECISION: scheduled 재스캔 주기(아래 표의 daily) — Trivy DB 는 ~6h 갱신이나 재스캔 cron 빈도는 외부 표준 없음(team-policy). trade-off: daily = 신규 CVE 노출 ≤24h vs CI 비용. 더 잦으면 noise/비용↑.
  • UNSUPPORTED_IMPL_DECISION: 멀티모듈 lockfile --file-patterns "gradle-lockfile:*.lockfile" — Trivy 공식 문서 미명시 workaround(GitHub Discussion #9740). trade-off: ca-tmpl 실제 lockfile 명명(gradle.lockfile vs gradle/dependency-locks/*.lockfile)에 맞춰야 함 → Claims To Verify.
단계(stage) 도구 scan-type trigger severity gate 잡는 것
PR — 신규 도입 차단 dependency-review-action (REST API diff) pull_request fail-on-severity: high PR diff 로 새로 들어온 취약 의존성 (D7)
PR — 전체 스냅샷 Trivy fs (lockfile) pull_request exit-code:1 + severity:CRITICAL,HIGH 기존+신규 전체 의존성 CVE (D1)
scheduled 재스캔 Trivy fs (lockfile) schedule(daily) 동일 의존성 불변이라도 새 CVE DB 로 새로 매치된 취약점
pre-release Trivy image release tag 동일 컨테이너 이미지 OS/런타임 패키지 취약점 — severity 정책만 본 branch, wiring 은 raw/branch-notes/feature-container-runtime-contract

2. Severity 판정 매트릭스 (CVSS + KEV + EPSS)

Trace: D2 (vuln-severity-cvss-v31-spec-first-official#C1·#C2·#C3), D3 (vuln-severity-cisa-kev-catalog-official#CISA-KEV-C1·#C3), D8 (UNSUPPORTED — FIRST EPSS deferred), D4 (trivy-java-language-coverage#C5). 이 매트릭스는 ci-gates·container-runtime·supply-chain 이 공유 consume 하는 단일 severity 표준.

  • UNSUPPORTED_IMPL_DECISION: "≥High 차단" 임계값 — FIRST.org 는 밴드(C1)만 표준화하고 어느 등급부터 차단인지 는 소비자 책임(C2)으로 명시. ≥High 차단은 industry de-facto(GitHub/Snyk/OSV-Scanner default). trade-off: ≥Medium 차단 시 FP noise 급증; Critical-only 차단 시 exploit code 있는 High 누수.
  • UNSUPPORTED_IMPL_DECISION: EPSS 임계값 0.1 — FIRST top-decile practitioner 합의, 공식 차단 mandate 없음. trade-off: 낮추면 FP↑. (D8 자체가 optional)
입력 None 0.0 Low 0.13.9 Medium 4.06.9 High 7.08.9 Critical 9.010.0
기본 게이트 결정 pass pass(report) warn(advisory) block block
KEV 등재 시(D3) block block block block block
EPSS ≥ 0.1 시(D8) review ticket review ticket (이미 block) (이미 block)
  • 소스 우선순위(D4): 동일 CVE 의 점수가 NVD vs GHSA 로 다르면 Java/Gradle 패키지는 GHSA 우선 → NVD fallback. (단 §Open Risk: 언어-패키지 override 명시 verbatim 미확보.)

3. Suppression governance

Trace: D5 (trivy-filtering-suppression-policy#C1·#C3·#C4·#C5). 2026-05-25 ca-tmpl audit .trivyignore 무단 우회 finding 해소.

  • UNSUPPORTED_IMPL_DECISION: 만료 기간 상한(예: 90일)·승인 권한(CODEOWNERS 대상)·무단변경 차단 게이트의 구현 메커니즘(CI step regex vs CODEOWNERS protected path) — Trivy 문서는 expired_at 필드 존재만 보장(C4), 정책 수치는 권고 안 함. trade-off: 짧으면 재검토 부담↑, 길면 사실상 영구 ignore.
규칙 강제 방법 근거
suppression 은 .trivyignore.yaml 단일 파일 CI 가 인라인 ignore/CLI --ignore 사용 금지 검사 C2 (구조화 YAML)
각 항목 만료일 필수 (expired_at 누락 금지) CI 정적 검사: expired_at 없는 row fail (C4: 미지정시 영구유효 → 금지) C4
각 항목 statement 사유 필수 CI 정적 검사: statement 빈 row fail C5
.trivyignore.yaml 변경은 PR 승인 필수 역할 분리(둘 다 필요): ① CODEOWNERS protected path + branch protection = merge-time 승인 강제(GitHub native), ② CI step regex = expired_at/statement 필드 검증(CODEOWNERS 가 못 하는 내용 검증) audit finding

UNSUPPORTED_IMPL trade-off (위 표 ② 보강): 무단 변경 차단의 1차 메커니즘은 CODEOWNERS protected path(GitHub-native, merge 차단). 단 CODEOWNERS 는 파일 변경 승인만 강제하고 만료일·사유 누락은 못 잡으므로 CI regex step 이 병행 필수 — 둘은 대체재가 아니라 보완재.

4. 의존성 보안 업데이트 자동화 + transitive 처리

Trace: D6 (renovate-vulnerability-alerts-gradle-official#C1·#C2, dependabot-security-updates-gradle-official#C1·#C2·#C3·#C5). supply-chain D3(Renovate/Dependabot) 정합.

  • UNSUPPORTED_IMPL_DECISION: patch-level 보안 PR auto-merge — Renovate automerge+matchUpdateTypes:["patch"] 조합은 일반 기능이나, patch 만 auto-merge / minor·major 는 human review 경계는 team-policy(이 페이지 미아카이브). trade-off: CI 커버리지 낮으면 취약 patch 자동 merge 위험.
  • UNSUPPORTED_IMPL_DECISION: osvVulnerabilityAlerts on/off — experimental 상태(needs-confirmation). 기본 vulnerabilityAlerts(GitHub Alerts, stable) primary, osv 는 maven 커버리지 검증 후 opt-in.
항목 정책 비고
primary 도구 Renovate security:only-security-updates preset C1 (osv+vulnerabilityAlerts 활성)
조건부 대안 Dependabot (조직 표준 또는 lockfile 미사용) #12557 lockfile+catalog 충돌 회피가 Renovate 선택 이유
patch 보안 PR CI green 시 auto-merge UNSUPPORTED_IMPL (위)
minor/major 보안 PR human review 필수 breaking 위험
transitive 취약점 Renovate/Dependabot 미커버(직접 의존성만) → Gradle dependencies { constraints { } } 또는 resolutionStrategy.force 로 수동 override UNSUPPORTED_IMPL: Gradle 메커니즘 선택. supply-chain D8 locking 과 정합 필요

5. 의존성 라이선스 준수 스캔 (license/NOTICE)

Trace: D10 (trivy-java-language-coverage#C1*gradle.lockfile License ✓; github-dependency-review-action#C5 — allow/deny license list). governing §35-E L2052 가 license scan 을 본 branch 영역으로 명시.

  • UNSUPPORTED_IMPL_DECISION: 금지/허용 SPDX 라이선스 목록 — 어떤 라이선스(예: GPL-3.0/AGPL-3.0 strong-copyleft)가 release-blocking 인지는 조직 법무/정책. Trivy/GitHub 문서는 스캔·allow/deny 메커니즘만 보장. trade-off: 보수적(allow-list only) = 신규 의존성 마찰↑; 관대(deny-list) = 누락 위험.
단계 도구 동작 근거
PR-time 신규 라이선스 차단 dependency-review-action allow-licenses/deny-licenses 목록으로 PR diff 의 새 의존성 라이선스 검사 github-dependency-review-action#C6
전체 스냅샷 license scan Trivy (D1 과 동일 fs scan) *gradle.lockfile License 컬럼 — 별도 도구 불필요 trivy-java-language-coverage#C1
forbidden 라이선스 발견 release-blocking CVE 차단(D2)과 동일 게이트 계열 정책(UNSUPPORTED_IMPL: 목록)

Audit & Findings — Single-Owner 정합 (cross-branch)

본 branch 가 §25 SSOT Owner Map 에 부재하던 dependency vulnerability 정책 owner 로 신설되며 해소하는 cross-branch finding. consistency-contract §전파의 역참조 비차단 알림 대상(쓰기 시 hook 이 ci-gates:255 → D5 참조를 3회 알림). 아래는 owner 확정 + sibling 갱신 권고(비차단 — 본 branch 머지와 독립).

1. OWNER 확정 (Cross-Branch Conflict Procedure §25 통과)

  • §25 SSOT Owner Map contract area grep: "vulnerability"/"dependency vulnerability" owner 부재 확인 → 본 branch 가 new owner 자격.
  • sibling grep 결과 동일 영역 스텁 3건 발견(모두 UNSUPPORTED, 검증 깊이 0 → 시간순·도메인 우선 원칙상 전용 branch 가 SSOT):
    • ci-gates D5 + §Audit OWNER_AMBIGUITY: "scanner tool 선택 미결 → dependency-vulnerability 또는 supply-chain 으로 위임" → 본 branch D1 이 Trivy 로 확정(미결 해소).
    • supply-chain D2 (high/critical=release-blocking, UNSUPPORTED, "CVSS 외부 표준 보강 권고") → 본 branch D2/D3 이 CVSS v3.1 + KEV 표준 부여.
    • supply-chain D3 (Renovate/Dependabot, UNSUPPORTED → 2026-06-15 official-vendor-doc 로 전환: raw/official-docs/renovate-gradle-manager-official RENOV-GRAD-C1~C4) → 본 branch D6 이 security-update 정책 owner 로 확정 (supply-chain D3 는 Gradle 지원 범위·lockfile·supply-chain 제약 raw 소유).

2. Sibling 역참조 갱신 권고 (비차단, 다음 작업자//sync)

대상 현재 갱신 후
ci-gates D5 / §Audit OWNER_AMBIGUITY "scanner tool 선택 미결" "scanner = feature-dependency-vulnerability-management-contract D1 (Trivy, 결정 완료)"
ci-gates Gate 매트릭스 "vulnerability scan" owner 열 severity=supply-chain / tool=dependency-vuln(미결) severity·tool·suppression 정책 = dependency-vuln D1~D5; gate 배선 만 ci-gates
supply-chain D2 UNSUPPORTED (severity 표준 보강 권고) "severity 표준 = dependency-vuln D2(CVSS v3.1)+D3(KEV); 본 D2 는 release-block 시점/posture 만 소유"
supply-chain D3 UNSUPPORTEDofficial-vendor-doc 로 갱신됨 (2026-06-15: raw/official-docs/renovate-gradle-manager-official RENOV-GRAD-C1~C4 등록) "security-update 정책 owner = dependency-vuln D6; supply-chain D3 는 Gradle 파일 패턴·lockfile 갱신·supply-chain 제약 근거를 소유"
container-runtime (image-scan Decision 부재) image scan/Trivy/severity 결정 0건 → 본 branch 의 consumer 링크가 dangling container-runtime 에 "image vuln scan = Trivy image, severity 정책 = dependency-vuln D2/D3 consume" Decision 신설 권고(없으면 §구현가이드 §1 pre-release row 의 wiring owner 가 미존재)
프로젝트노트 §25 SSOT Owner Map (row 없음) 신규 row: dependency vulnerability policy | feature-dependency-vulnerability-management-contract | consumers: ci-gates(gate wiring)·container-runtime(image scan)·supply-chain(release-block posture)본 루프에서 프로젝트노트에 직접 추가함(coverage Should-fix 해소)

3. Producer/Consumer 경계 (재진술 금지 — Reference-Only)

  • 본 branch = producer of severity 표준 + scanner + suppression + update 정책.
  • ci-gates·container-runtime·supply-chain = consumer (배선/시점만). 본 branch 는 그들의 wiring 을 재진술하지 않고, 그들은 본 branch 정책을 재진술하지 않고 [[...]] D<n> 포인터로만 인용.

4. OUT_OF_BRANCH_SCOPE (본 branch 로 끌어오지 않음)

  • secret scan(gitleaks) → secrets-config-source. container base image 선택 + image scan wiring → container-runtime. CI gate needs:/if: 배선 → ci-gates. SBOM/서명/version-locking → supply-chain. (본 branch 는 정책만 — 위 항목의 detail 을 §구현가이드에 남기지 않음.)
  • 정정(2026-06-15 coverage 루프): license/NOTICE scan 은 OUT_OF_BRANCH_SCOPE 가 아님 — governing §35-E L2052 가 본 branch 영역으로 명시했고 supply-chain 은 license 결정 0건이라 delegated owner 부재였음. → D10 으로 본 branch 가 covered-here.

엣지·실패·의존

R4(깊이 게이트) 캡처용. 정상 경로 외에 구현 중 부딪힐 실패/엣지/다른 계약 의존을 미리 열거.

  • 실패·엣지 경로:
    • 스캐너 DB 미가용/네트워크 차단 (CI 러너 air-gap, Trivy DB pull 실패) → 스캔이 silent pass 하면 안 됨. 기대: DB fetch 실패 = job fail (취약점 0 보고와 구분). Trivy --exit-code 와 별개로 DB 갱신 실패 fail-fast 검증 필요(Claims To Verify).
    • False positive 차단 (Gradle force=true 재정의, backport patch 미인식) → 잘못된 release block. 기대: D5 suppression 으로 만료일+사유 달고 우회, 영구 ignore 금지.
    • Transitive 취약점에 직접 fix 없음 → Renovate/Dependabot PR 생성 실패(직접 의존성만). 기대: Gradle constraint 수동 override (§구현가이드 §4), supply-chain D8 lock 재생성.
    • NVD enrichment 공백 (2026-04 정책 변경, 신규 CVE CVSS 미부여) → severity 미상으로 게이트 통과. 기대: GHSA fallback(D4) + KEV(D3) 가 점수 없는 악용 CVE 를 잡음.
    • Multi-module lockfile 미탐지 → 일부 subproject 스캔 누락(취약점 silent miss). 기대: --file-patterns + 각 subproject lockfile 커밋 검증.
    • .trivyignore 무단 추가로 긴급 우회 → 2026-05-25 audit finding. 기대: D5 정적 게이트가 무단 변경 차단.
    • dependency-review-action fail-open (Gradle dependency graph 미제출 → 빈 diff = 0 취약점 pass) → PR 게이트가 거짓 통과. Trivy DB fail-open 과 동일 계열. 기대: graph 제출 검증 step(없으면 fail) + D1 Trivy fs 전체 스캔이 backstop(D7 단독 게이트 금지 이유).
  • 다른 계약 의존 (cross-contract):

검증해야 할 주장

공식 문서나 사례는 근거지만, 내 프로젝트에서의 동작을 자동으로 보장하지 않는다. 구현 전/중/후에 실제로 검증해야 하는 주장을 분리한다.

Claim Why uncertain How to verify Status
Trivy --file-patterns "gradle-lockfile:*.lockfile" 가 ca-tmpl 실제 lockfile 명명을 탐지 공식 문서 미명시 workaround(#9740); ca-tmpl lockfile 명명(gradle.lockfile vs gradle/dependency-locks/*.lockfile) 미확정 ca-tmpl 에 gradle dependencies --write-locks 실행 → lockfile 생성 후 trivy fs --file-patterns ... 가 각 subproject 탐지하는지 verify needs-confirmation
Java/Gradle 패키지에서 GHSA 점수가 NVD 점수를 override (D4 tie-break) coverage 페이지는 OS 패키지만 vendor>NVD 우선 명시; 언어 패키지 override verbatim 미확보 trivy.dev/docs/latest/scanner/vulnerability/ 소스 우선순위 페이지 아카이브 + NVD/GHSA 점수 다른 known CVE 로 Trivy 출력 severity 확인 needs-confirmation
Renovate vulnerabilityAlerts 가 schedule 을 무시하고 즉시 PR + osvVulnerabilityAlerts maven 커버 presets 페이지에서 schedule-ignore·osv experimental·maven datasource 미확인(summarizer 폐기) configuration-options#vulnerabilityalerts·#osvvulnerabilityalerts 아카이브 + 실제 repo 에 known-vuln dep 추가 → 즉시 PR 생성 verify needs-confirmation
Dependabot Gradle security update 가 libs.versions.toml+lockfile 동시 사용 시 lockfile 갱신 (#12557) about 페이지는 Gradle 지원을 링크로 위임; #12557 미해결(2025-07) supported-ecosystems 페이지 + #12557 상태 확인; 테스트 repo 로 Dependabot security PR 이 lockfile drift 유발하는지 verify needs-confirmation
Dependabot 은 dependabot.yml native auto-merge 없음 → Renovate 대비 복잡 about 페이지에 auto-merge 키워드 0건(summarizer 확인) automating-dependabot-with-github-actions 페이지 아카이브로 auto-merge 가 Actions workflow 필요함 확정 needs-confirmation
KEV "exploited in the wild" 정의 + 비연방 권고 + BOD 26-04 4-factor CISA HTML 403 으로 JSON feed 만 확보(정의·권고 미인용) CISA 카탈로그 About + BOD 26-04 페이지 접근 가능 시 별도 raw 아카이브(bod-26-04-...) needs-confirmation
dependency-review-action 이 Gradle 의존성 diff 를 보려면 dependency graph 제출 필요 Gradle dependency graph 자동 추출 vs submission API 경로 불확실 GitHub dependency graph 가 Gradle 프로젝트를 인식하는지 + dependency-submission action 필요 여부 확인 needs-confirmation
스캐너 DB fetch 실패가 silent pass 가 아니라 job fail Trivy --exit-code 는 취약점 발견용; DB 갱신 실패 시 동작 미확정 CI 에서 DB endpoint 차단 후 Trivy 실행 → exit code 검사; fail-fast 안 되면 --exit-on-eol/DB 검증 step 추가 planned
scheduled 재스캔이 의존성 불변 상태에서 신규 CVE 를 실제로 잡음 CVE DB 갱신만으로 새 매치가 생기는지 실증 필요 known-clean dep 고정 후 일정 기간 뒤 재스캔 → 그 사이 공개된 CVE 가 잡히는지 verify planned
.trivyignore.yaml 무단 변경 차단 정적 게이트가 우회 불가 (D5/audit 해소) 게이트 구현(regex/CODEOWNERS) 미확정 .trivyignore.yaml 에 만료일·사유 없는 row 추가 PR → CI fail + CODEOWNERS 승인 없이 merge 불가 verify planned

관심사 커버리지 (coverage-auditor 자동 생성 — 있을 때)

/coverage 가 채우는 생성물 — 손으로 유지하지 않는다. governing 문서(frontmatter governing_docs)가 요구하는 관심사를 이 브랜치가 빠짐없이 덮는지의 결과. 기준: rules/coverage-gate.md. 상태: covered-here(이 브랜치 결정) / delegated(다른 owner 브랜치) / missing(아무도 안 맡음 → Blocking).

출처: /coverage (coverage-auditor, 2026-06-15, governing = raw/project-notes/ca-skeleton-operational-contract §18 + §35-E L2052). 1차 Not-covered(missing 1: license scan) → 본 루프에서 D10 추가로 covered-here 전환 → Covered.

관심사 상태 owner 심각도 근거
CVE scan 도구 선택(SCA 스캐너) covered-here D1 (Trivy)
severity별 release-block 기준(CVSS 임계값) covered-here D2 (CVSS v3.1 ≥High)
KEV override covered-here D3
소스 우선순위 tie-break(GHSA vs NVD) covered-here D4
Suppression governance covered-here D5
의존성 보안 업데이트 자동화(Renovate/Dependabot) covered-here D6
PR-time 보완 게이트(dependency-review-action) covered-here D7
EPSS escalation(비차단) covered-here D8 (UNSUPPORTED, optional)
Remediation SLA by severity covered-here D9 (UNSUPPORTED, team-policy)
license/NOTICE compliance scan covered-here D10 (Trivy license + dep-review allow/deny; governing §35-E L2052)
Transitive 취약점 처리 covered-here §구현가이드 §4 (D6 도출)
Scheduled re-scan(CVE DB 갱신) covered-here §구현가이드 §1
CI gate wiring(blocking vs warning) delegated raw/branch-notes/feature-ci-quality-gates-contract OK Out of scope; ci-gates §Coverage L283 역참조 존재
dependency version locking delegated raw/branch-notes/feature-build-release-supply-chain-contract OK supply-chain D8
SBOM·서명(Cosign/SLSA)·versioning·rollback delegated raw/branch-notes/feature-build-release-supply-chain-contract OK supply-chain D4/D6/D7/D9/D11
container image scan wiring + base image delegated raw/branch-notes/feature-container-runtime-contract Should-fix §Audit — container-runtime 에 image-scan Decision 부재(dangling consumer link) → 신설 권고
secret scan(gitleaks) delegated raw/branch-notes/feature-secrets-config-source-contract OK Out of scope

마주친 문제

짧은 메모만. 깊이 있는 트러블슈팅은 raw/errors/ 로 분리하고 아래 Cluster에 연결.

  • 이슈 1
    • 원인:
    • 시도:
    • 해결: (또는 미해결이면 needs-confirmation)
    • 별도 에러 노트로 분리됨: [[raw/errors/<...>]] (생성 시)

묶음 (이 branch에서 파생된 자료)

이 branch는 단일 노트가 아니라 작업 묶음의 entry point. 이 branch에서 파생된 모든 raw 노트를 카테고리별로 명시. 자식 노트가 forward link만 박아도 Obsidian backlink로 자동 발견되지만, 읽기 흐름과 분류를 위해 hub가 명시적으로 그룹화한다.

Sub-branches (세부 작업)

  • 없음 — 단일 branch 로 구현. 세부 작업 분기 불필요.

오류 기록 (이 branch 작업 중 발생)

  • raw/errors/gitea-act-action-tag-and-dependency-graph-2026-06-20 — commit 후 Gitea/act 첫 실행에서 CI 2개 잡 실패: trivy-action 태그 오타(@0.28.0@v0.28.0) + dependency-review 의 Gitea dependency-graph API 부재(server_url 가드). egress 가설을 로그로 반증한 evidence-first 사례.
  • (구현 단계 자체는 blocking 오류 없음 — lockfile 부재로 Trivy fs 가 Gradle deps no-op 인 것은 오류가 아니라 문서화된 cross-contract 선행조건, supply-chain D8.)

면접 준비 (이 작업에서 나올 수 있는 면접 질문)

강의 (이 작업을 위해 학습한 강의)

  • 없음 — 외부 강의 학습 없이 공식 문서(Trivy/CISA-KEV/FIRST/Renovate/GitHub) 근거로 구현.

job-posting tie-ins (이 작업에서 파생된 글감)

관련 일일 노트

이 브랜치를 작업한 날짜들. 양방향 nav 유지.

  • [[raw/daily-notes/YYYY-MM-DD]]
  • [[raw/daily-notes/YYYY-MM-DD]]

완료 후 정리

머지/종료 시점에 채움. /ingest가 이 섹션을 기준으로 wiki/projects/에 추출.

  • PR 링크:
  • 리뷰 메모:
  • 머지 결과 / 배포 환경: (로컬/dev/staging/prod 어디까지 검증됐는지)
  • wiki 추출 대상 (verified만, wiki/projects/로만 추출):
    • actually-implemented 항목:
    • locally-verified 항목:
    • prod-verified 항목:
  • 추출하지 않을 항목 (planned / documented-only / abandoned):