취약점
Vulnerabilities 탭은 스캔 파이프라인이 프로젝트 컴포넌트와 상관시킨 모든 미해결 CVE(Common Vulnerabilities and Exposures)를 나열합니다. 결과는 스캔을 거쳐 영속화됩니다. CVE가 한번 발견되면 근본 컴포넌트가 제거·업그레이드될 때까지 상태와 분류 노트와 함께 프로젝트 이력에 남습니다.

개별 결과를 분류하는 엔지니어; SLA를 추적하는 보안 리드. VEX 상태 변경은 developer 이상; 일괄 억제는 team_admin.
"Vulnerability data unavailable" 배너
Vulnerabilities 탭 상단에 파란색 Vulnerability data unavailable 배너가 나타나는 경우는, 포털이 스캔에서 발견한 컴포넌트는 보여줄 수 있지만 finding이 0 건일 때 — 보통 로컬 Trivy DB의 다운로드가 아직 끝나지 않았거나(워커가 막 부팅한 신규 배포), DB 다운로드가 실패한 경우입니다. 배너는 원인을 설명하고 다음 절차를 안내합니다.
- 관리자는 워커 디스크의 Trivy DB를 확인해야 합니다 — 정확한 명령은 취약점 데이터 — 동작 확인 참조. 곧 도착할
/admin/health하위의 Vulnerability data 카드(roadmap)가 UI에서 신선도를 노출합니다. - Trivy DB가 자리 잡으면 자동 재매칭 beat이 모든 프로젝트의 최신 SBOM에서 finding을 가져옵니다 — 사용자 측 인앱 액션은 필요 없습니다. 배너는 적어도 한 건의 finding이 반환되는 다음 페이지 로드에서 자동으로 사라집니다.
배너는 정보성 이지 에러가 아닙니다 — 실제로 깨끗한 프로젝트의 0 findings는 API 레벨에서 동일하게 보이므로, 메시지는 의도적으로 단정하지 않고 진단 표면을 가리킵니다.
심각도 모델
| 심각도 | 색상 토큰 | CVSS v3 (일반) | 빌드 게이트 |
|---|---|---|---|
| Critical | #dc2626 | 9.0–10.0 | 종료 코드 1(기본) |
| High | #ea580c | 7.0–8.9 | 프로젝트별 설정 |
| Medium | #ca8a04 | 4.0–6.9 | 영향 없음 |
| Low | #2563eb | 0.1–3.9 | 영향 없음 |
| Info | #71717a | — | 영향 없음 |
기본 정책은 Critical에서만 빌드를 실패시킵니다. 프로젝트 소유자는 임계치를 High로 낮출 수 있습니다.
VEX 상태 머신
결과는 CycloneDX VEX(Vulnerability Exploitability eXchange) 7-state 모델을 따릅니다. 각 결과는 신규에서 시작하며 분석가가 분류함에 따라 전환됩니다.
| 상태 | 정의 | 빌드 게이트 |
|---|---|---|
| 신규 (New) | 막 발견됨; 분류되지 않음. | 카운트. |
| 분석 중 (Analyzing) | 분류 진행 중. | 카운트. |
| 악용 가능 (Exploitable) | 이 프로젝트 맥락에서 악용 가능 확인. | 카운트. |
| 해당 없음 (Not affected) | 컴포넌트는 있으나 취약 코드 경로에 도달 불가. | 제외. |
| 오탐 (False positive) | 탐지 자체가 잘못됨(예: 잘못된 purl). | 제외. |
| 억제됨 (Suppressed) | 운영자가 명시적으로 침묵 처리(not_affected + 명시적 억제). | 제외. |
| 수정됨 (Fixed) | 해결됨(컴포넌트 업그레이드 또는 패치 적용). | 제외. |
전환은 행위자, previous_status, new_status, 필수 사유 메시지와 함께 감사 로그에 기록됩니다.
필수 사유
New / Analyzing 외 상태로 전환할 때마다 자유 텍스트 사유(10자 이상)가 필요합니다. 포털은 사유를 그대로 저장합니다 — 사실 기반으로 작성하세요("lodash를 4.17.21로 업그레이드", "취약 코드 경로는 dev_only 모듈에 있음"). 본 텍스트는 CycloneDX VEX 출력에 그대로 노출됩니다.
다른 사람의 동의가 필요한 상태
기본값에서는 권한을 가진 분석자가 혼자 항목을 닫습니다. 조직에 따라 어떤
결과는 한 사람이 정할 일이 아니라고 볼 수 있습니다. 항목을 Suppressed나
Not affected로 닫으면 취약점을 고치지 않은 채 의무가 끝나기 때문에, 이
결정만큼은 다른 사람이 동의한 뒤에 적용되기를 바라는 팀이 있습니다.
관리자가 [정책] - [빌드 게이트] - [다른 사람의 동의가 필요한 상태]에서 상태별로 켭니다. 기본값은 아무것도 선택되지 않은 상태이고, 선택이 없으면 모든 전환은 지금처럼 한 번의 동작으로 끝납니다.
상태를 선택하고 나면 이렇게 동작합니다.
- 평소의 전환은
409와 사유로 거절되고 항목은 움직이지 않습니다. 대량 전환과 VEX 문서 가져오기에도 똑같이 적용되므로, 여러 건을 한 번에 바꾸거나 문서를 올리는 방법으로 우회할 수 없습니다. 가져오기는 해당 구문만approval_required사유로 건너뛰고 나머지는 평소대로 반영합니다. - 사유를 적고 [동의 요청 보내기]를 누릅니다. 요청만 기록되고 항목은 그대로입니다.
- 요청은 그 팀을 관리하는 사람들의 [승인] 화면에 나타납니다. 요청한 본인에게는 버튼 없이 대기 중으로 보입니다.
- 다른 팀 관리자가 동의하거나 거절합니다. 동의하면 항목이 옮겨지고 직접 전환과 똑같이 감사 기록이 남습니다. 거절하면 항목은 그대로 두고 거절한 사실이 기록으로 남습니다.
켜기 전에 알아 둘 제약이 두 가지 있습니다.
- 요청한 사람은 승인할 수 없습니다. 역할이 아니라 사람 단위로 막기 때문에, 관리자가 한 명뿐인 팀에서는 어떤 요청도 끝낼 수 없습니다. 먼저 관리자를 한 명 더 두세요.
- 한 항목에 열려 있는 요청은 하나뿐입니다. 대기 중에 들어온 두 번째 요청은 거절되므로, 승인하는 사람이 서로 다른 두 제안 중 무엇을 정하는지 헷갈릴 일이 없습니다.
요청이 대기하는 동안 항목이 다른 상태로 옮겨졌다면(예를 들어 누군가 다시 열었다면)
그 요청에 동의하는 시도는 422로 실패하고 요청은 열린 채로 남습니다. 일어나지
않은 일에 동의한 기록을 남기지 않기 위해서입니다.