62 KiB
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 |
|
|
|
2026-06-15 | in-progress | BR-CA-SKELETON-OPERATIONAL-CONTRACT-051 | project-work-item | ca-skeleton-operational-contract | WI-CA-SKELETON-OPERATIONAL-CONTRACT-051 |
|
|
1 | bb574e1b56cc247fc24b861ef1249c28991938b0dab6bab63999d5cf9ffb756b |
branch: feature-dependency-vulnerability-management-contract
Layer:
raw/branch-notes/— 단일 브랜치의 TODO·결정·진행 기록. 머지/종료 후 verified 결과는/ingest로wiki/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 와 계약 경계를 공유):
- raw/branch-notes/feature-build-release-supply-chain-contract — SBOM·서명(Cosign/SLSA)·dependency locking·artifact versioning 의 owner. 본 branch 는 그 D2(high/critical=release-blocking)·D3(Renovate/Dependabot) 의
UNSUPPORTED_DECISION스텁을 승계해 정책 owner 가 된다(아래 §Audit & Findings). - raw/branch-notes/feature-ci-quality-gates-contract — CI gate wiring(release-blocking vs warning-only) 의 owner. 본 branch 의 severity 정책을 consume. 그 D5(Trivy scanner+suppression)
UNSUPPORTED_DECISION스텁도 본 branch 가 정책 owner 로 정합. - raw/branch-notes/feature-container-runtime-contract — container image scan wiring + base image(Temurin JRE slim) owner. 본 branch 의 동일 severity 정책을 consume.
브랜치 계약 패킷
- 생성 시 프로젝트 개정:
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-contractowner. 본 branch 는 정책을 제공만. - container image scan wiring + base image 선택 —
feature-container-runtime-contractowner (본 branch severity 정책 consume). - SBOM 생성·artifact 서명(Cosign/SLSA)·dependency version locking·artifact versioning·rollback —
feature-build-release-supply-chain-contractowner. - secret scan(gitleaks) —
feature-secrets-config-source-contractowner. - 특정 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.ymltrivy-fs잡, YAML valid; 실제 CI 실행은needs-confirmation) (D1) dependency-review-actionrequired check (fail-on-severity: high) — 등급:actually-implemented(.github/dependency-review-config.yml+ workflowdependency-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.yamlsuppression 정책 + 만료일 강제 + 무단변경 차단 정적 게이트 — 등급:locally-verified(verifyTrivyignoreGradle gate: 6-케이스 pass/fail 검증 +./gradlew checkgreen;.trivyignore.yaml빈 seed +.github/CODEOWNERSmerge-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 imagescan — 등급:actually-implemented(workflowscheduledaily cron +trivy-imagerelease 잡,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_DECISIONteam-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— D1trivy-fs(PR+daily schedule,scanners: vuln,license,severity: CRITICAL,HIGH,exit-code:1,trivyignores: .trivyignore.yaml,TRIVY_FILE_PATTERNS) + D7dependency-review(PR) +dependency-submission(gradle/actions/dependency-submission, graph fail-open 보강) + §1trivy-image(release,vars.RELEASE_IMAGE_REF게이팅 — container-runtime wiring seam)..github/dependency-review-config.yml— D7fail-on-severity: high+fail-on-scopes: [runtime]+ D10deny-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— D6config: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→@DongHyeonkaplaceholder)..github/dependency-vulnerability-policy.md— D2/D3/D4/D8/D9/D10 통합 정책 SSOT(committed). 모든 team-policy 수치UNSUPPORTED_IMPL_DECISION라벨.src/build.gradle— D5 §3 ①verifyTrivyignoreGradle 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 wiring 은 vars.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 gaterun step(CISA KEV JSON feedcurl -fsSL --retry 3→jq/comm으로 발견 CVE ∩ KEV → 교집합 있으면exit 1) 추가. suppression(.trivyignore.yaml)은 그대로 적용 → KEV CVE 는 거버넌스된 suppression 으로만 수용. feed 미가용 =curl -ffail-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.0→Unable 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.04건 grep 확인, GitHub API 로v0.28.0존재 확인. (YAML 변경만 —./gradlew무관.) 재실행 후 trivy-fs 완전 통과(Trivy DB pull + KEV step cisa.gov curl 포함)는needs-confirmation. trivy-fs2차 실패 → 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 imageCLI 직접 호출.--file-patterns제거(**/*.lockfile는 CLI 에서 invalid regex 위험 + 표준gradle.lockfile명명은 Trivy 기본 탐지로 충분; 비표준 명명만 Claims To Verify). KEV step 에KEV_FEED_URLrepo-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 imageCLI 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.lockfilelicense 도 스캔하므로 별도 도구 불필요; 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 Claims는raw/<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.0–6.9)/Low(0.1–3.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 (필수 준수):
- R1. Reference 필수 — 각 sub-section / row / cell 은 본 branch 의
Decision ID(예: D1, D2) + 그 결정의Supporting Claim ID(예:RAW-SLUG-C1) 를 reference. 근거 없는 결정 금지 — 모든 구현 detail 은 결정 + 근거의 도출 이어야 함.- R2. UNSUPPORTED_IMPL_DECISION 명시 — 근거 raw 가 원칙 만 권고하고 detail (메커니즘 선택 / 클래스/rule 명명 / glob 패턴 / algorithm / factory API 모양 등) 은 권고하지 않는 cell 은
UNSUPPORTED_IMPL_DECISION라벨 + 사용자 trade-off 근거 한 줄. 이게 근거 있는 결정 vs 사용자 임의 trade-off 의 경계.- 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.lockfilevsgradle/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.1–3.9 | Medium 4.0–6.9 | High 7.0–8.9 | Critical 9.0–10.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:
osvVulnerabilityAlertson/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.lockfileLicense ✓;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 areagrep: "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-15official-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 소유).
- ci-gates D5 + §Audit
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 | official-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 단독 게이트 금지 이유).
- 스캐너 DB 미가용/네트워크 차단 (CI 러너 air-gap, Trivy DB pull 실패) → 스캔이 silent pass 하면 안 됨. 기대: DB fetch 실패 = job fail (취약점 0 보고와 구분). Trivy
- 다른 계약 의존 (cross-contract):
- 소비자 (본 branch 정책을 consume): raw/branch-notes/feature-ci-quality-gates-contract D5(gate wiring — vuln scan 의 release-blocking 배선), raw/branch-notes/feature-container-runtime-contract (image scan wiring, 동일 severity 정책 consume), raw/branch-notes/feature-build-release-supply-chain-contract D2(release-block 시점에 본 branch severity 표준 사용).
- 생산자 (본 branch 가 consume): raw/branch-notes/feature-build-release-supply-chain-contract D8(Gradle dependency-locking — Trivy
*gradle.lockfile스캔의 선행조건; lock 없으면 D1 스캔 불가) + D5(container base = Temurin JRE slim — image scan 대상). 이 계약이 바뀌면(예: lockfile 명명/위치 변경) 본 branch 의--file-patterns와 D1 스캔이 영향. - owner 정합 필요 (비차단 전파, §Audit): supply-chain D2/D3, ci-gates D5 의
UNSUPPORTED/OWNER_AMBIGUITY스텁이 본 branch 를 정책 owner 로 가리키도록 갱신돼야 single-owner 완결.
검증해야 할 주장
공식 문서나 사례는 근거지만, 내 프로젝트에서의 동작을 자동으로 보장하지 않는다. 구현 전/중/후에 실제로 검증해야 하는 주장을 분리한다.
| 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 문서(frontmattergoverning_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에서 파생된 자료)
- raw/official-docs/dependabot-security-updates-gradle-official
- raw/official-docs/github-dependency-review-action
- raw/official-docs/renovate-vulnerability-alerts-gradle-official
- raw/official-docs/trivy-action-github-actions
- raw/official-docs/trivy-filtering-suppression-policy
- raw/official-docs/trivy-java-language-coverage
- raw/official-docs/vuln-severity-cisa-kev-catalog-official
- raw/official-docs/vuln-severity-cvss-v31-spec-first-official
- raw/blog-topics/gitea-act-dependency-security-gate-portability-2026-07-02
- raw/blog-topics/trivy-suppression-governance-static-gate-2026-06-20
이 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.)
면접 준비 (이 작업에서 나올 수 있는 면접 질문)
- raw/interviews/trivy-suppression-dual-control-governance-2026-06-20 — suppression 영구 우회 구멍을 CODEOWNERS(merge-gate) +
verifyTrivyignore(CI field-gate) 이중 통제로 막은 설계, Renovate vs Dependabot 선택 근거.
강의 (이 작업을 위해 학습한 강의)
- 없음 — 외부 강의 학습 없이 공식 문서(Trivy/CISA-KEV/FIRST/Renovate/GitHub) 근거로 구현.
job-posting tie-ins (이 작업에서 파생된 글감)
- raw/blog-topics/trivy-suppression-governance-static-gate-2026-06-20 — Gradle 정적 게이트로 supply-chain suppression 거버넌스(만료일·사유 강제) 강제하기 + audit finding 해소.
- derived blog: 생성 전. 생성 시
wiki/blog/<slug>-YYYY-MM-DD.md후보
관련 일일 노트
이 브랜치를 작업한 날짜들. 양방향 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):