← 보안과 신뢰
실전 가이드DEEPER INTO TECHNOLOGY

SBOM만 있으면 안전할까? Provenance·VEX로 배포를 판단하는 법

소프트웨어 의존성 목록인 SBOM을 받았을 때, 취약점 경보와 빌드 증거를 어떻게 연결해 배포 여부를 판단해야 할까?

먼저 읽는 핵심

SBOM은 무엇이 들어 있는지, provenance는 어떤 경로로 만들어졌는지, VEX는 특정 제품이 특정 취약점의 영향을 받는다는 판단인지 알려 준다. 세 자료를 받는 것만으로 검증이 끝나지는 않는다. 실제 배포 대상과 자료의 대상이 일치하는지, 누가 어떤 근거로 작성했는지, 판단 이후 무엇이 바뀌었는지를 확인해야 다음 행동을 정할 수 있다.

취약점이 하나 나왔다고, 같은 결론이 나오지는 않는다

문서 변환 서비스를 납품받는 개발팀을 생각해 보자. 공급자는 릴리스 2.4.1과 함께 SBOM을 제공했다. 보안 스캐너는 그 안의 가상 라이브러리 doc-codec 4.2에서 취약점을 찾았다고 알린다. 공급자는 “현재 제품은 영향 없음”이라는 VEX 문서도 보냈다. 배포 담당자는 어느 쪽을 따라야 할까?

먼저 스캐너가 찾은 구성품과 공급자가 평가한 제품이 지금 배포할 파일에 함께 연결되는지 확인해야 한다. SBOM이 이전 빌드의 목록일 수도 있고, 영향 없음 판단이 다른 기능 구성에만 적용될 수도 있다. 반대로 제품 안에 라이브러리가 있어도 취약한 코드가 빌드에서 제외된 경우라면, 버전 문자열만으로는 실제 영향을 설명하기 어렵다.

이 글은 이런 상황에서 증거를 읽는 순서를 제안한다. 릴리스·라이브러리·취약점은 모두 가상이며, 아래 판단은 실제 보안 사고나 스캐너 실행 결과가 아니다. 공식 규격의 역할을 설명한 뒤 개발팀이 재사용할 사례와 기록 양식으로 연결한다. 회사의 배포 정책이나 개별 취약점 분석을 대신하는 자동 승인 도구는 아니다.

목록, 생산 이력, 영향 판단을 따로 읽는다

SBOM은 Software Bill of Materials, 소프트웨어 구성 명세다. NTIA의 2021년 최소 요소 문서는 구성품 이름·버전·공급자뿐 아니라 의존 관계, 작성자, 작성 시점 등을 다룬다. 이 문서는 SBOM의 기초 개념을 설명하는 자료로 사용하며, 현재의 모든 조달·규제 요건을 대표한다고 보지는 않는다.

Provenance는 산출물이 만들어진 경로에 관한 증거다. SLSA v1.2의 빌드 provenance는 어떤 빌더가 어떤 빌드 정의와 입력으로 산출물을 만들었는지 표현한다. VEX는 Vulnerability Exploitability eXchange, 특정 제품에 대한 특정 취약점의 영향 판단을 전달하는 방식이다. CycloneDX도 VEX를 지원하며, 이 글의 상태 이름은 뒤에서 명시한 OpenVEX 규격을 따른다.

자료 먼저 답하는 질문 그것만으로 답할 수 없는 질문
SBOM 어떤 구성품과 의존 관계를 기록했나? 누락이 없는가, 코드가 안전한가, 실제 공격 경로가 있는가?
빌드 provenance 어떤 빌드 과정이 이 산출물을 만들었다고 증언하나? 그 소스에 취약점이 없는가, 우리 설정에서 안전한가?
VEX 이 제품은 이 취약점의 영향을 받는다고 판단했나? 다른 취약점도 없는가, 다른 빌드·설정에도 적용되는가?

이는 세 파일을 반드시 별도로 받아야 한다는 뜻이 아니다. 한 문서에 여러 정보를 담거나 서명된 증명으로 묶을 수 있다. 중요한 것은 파일 개수가 아니라 각 주장이 가리키는 대상과 작성 근거다. 서명된 SBOM도 내용의 완전성은 따로 따져야 하고, 서명된 영향 평가도 분석이 틀릴 가능성은 남는다.

첫 번째 연결: 이 자료는 어느 산출물의 것인가

릴리스 이름 2.4.1은 사람이 읽는 표지다. 같은 이름으로 다시 빌드한 파일이나 다른 플랫폼용 파일을 구분하기에는 부족할 수 있다. 실제로 배포할 아티팩트, 즉 실행 파일·패키지·이미지 같은 산출물을 식별하고 문서가 그 대상을 설명하는지 확인한다.

예를 들어 처음 받은 파일의 SHA-256을 H_A, 재빌드한 파일의 값을 H_B라고 쓰자. 이는 설명용 기호이며 실제 해시 문자열이 아니다. 두 값이 다르면 동일 바이트의 파일로 취급할 수 없다. 다만 digest가 일치한다는 사실만으로 작성자의 신뢰나 코드의 안전성이 생기지는 않는다. 공격자가 파일과 비교할 해시를 함께 바꿨다면 둘은 일치할 수도 있다.

SLSA의 산출물 검증 절차는 provenance의 서명과 신뢰 기준, subject에 기록된 산출물 digest, 기대한 빌더·소스 저장소·빌드 유형·외부 파라미터를 대조하도록 설명한다. “서명 검사 성공”이라는 한 줄만 보고 우리 조직이 승인한 빌드 경로인지 생략해서는 안 되는 이유다.

실무에서는 다음 세 질문을 한 묶음으로 남길 수 있다.

  1. 대상: 검증한 파일과 지금 배포하는 파일이 같은가? 컨테이너라면 멀티플랫폼 인덱스와 개별 플랫폼 이미지 중 어느 대상을 비교했는지도 적는다.
  2. 신뢰: 서명자와 빌더는 사전에 정한 신뢰 기준에 포함되는가? 납품 문서에 스스로 적은 빌더 이름만으로 승인하지 않는다.
  3. 기대 경로: 허용한 저장소·빌드 정의·외부 입력으로 만든 것인가? 서명이 맞아도 다른 저장소에서 온 결과라면 따로 처리한다.

SBOM 역시 해당 아티팩트와 연결되어야 한다. 다만 모든 SBOM 형식이 SLSA의 subject 필드를 쓰는 것은 아니다. SBOM 자체의 식별자·해시나 배포 시스템의 검증된 대응 관계로 연결할 수 있다. VEX도 제품 식별자와 버전 등으로 대상을 나타낼 수 있으므로, 모든 문서에서 같은 이름의 해시 필드를 찾는 방식으로 구현하면 안 된다.

이 단계의 실패는 우선 증거와 대상의 불일치다. 곧바로 악성 파일이라는 증명은 아니지만, 다른 파일의 검증 결과를 물려받아 새 배포를 승인할 근거도 없다. 공급자에게 정확한 대응 자료를 요청하고 배포 후보를 다시 고정하는 일이 먼저다.

두 번째 연결: 목록에 없다는 말의 범위를 묻는다

SBOM에서 doc-codec를 찾지 못했다고 하자. 가능한 설명은 두 가지다. 실제로 포함되지 않았거나, 조사한 범위에서 발견하지 못했거나. 잠금 파일만 읽은 목록과 최종 배포 이미지까지 조사한 목록은 이 질문에 같은 수준으로 답하지 못할 수 있다.

구체적으로는 생성 시점과 대상을 묻는다. 소스 저장소, 빌드 중간 단계, 최종 산출물 중 어디에서 만들었는가? 베이스 이미지의 OS 패키지, 복사해 넣은 바이너리, 정적으로 포함된 코드, 실행 후 가져오는 플러그인은 어느 자료가 담당하는가? 이는 특정 도구가 반드시 누락한다는 주장이 아니라, 팀이 목록의 관측 범위를 확인하기 위한 질문이다.

NTIA 문서의 Depth·Known Unknowns 절은 의존 관계의 깊이와 알려진 누락을 구분하고, 하위 의존성이 없다는 상태와 아직 모른다는 상태를 다르게 나타내도록 설명한다. 따라서 구성품 수가 많다는 이유만으로 완전한 목록이라고 보기는 어렵다.

SLSA provenance에 의존성 필드가 있다고 해서 SBOM 전체를 대체할 수도 없다. Build: Provenance의 resolvedDependencies 정의는 빌드 시 필요한 산출물을 다루며, 적어도 Build L3까지 완전성은 best effort라고 명시한다. 빌드 입력 이력과 최종 제품의 구성 명세는 목적과 수집 범위가 다르다.

독자가 할 일은 “누락 없음”을 무조건 요구하는 데서 끝나지 않는다. 당장 알 수 없는 범위를 적고, 이번 취약점 판단에 그 공백이 중요한지 정해야 한다. 예를 들어 OS 라이브러리 경보를 조사하면서 애플리케이션 패키지 목록만 갖고 있다면, 그 목록에서 검색을 반복해도 핵심 공백은 줄지 않는다. 최종 이미지나 OS 구성에 대한 자료가 필요하다.

세 번째 연결: 영향 없음은 무엇을 전제로 하는가

이 글에서 참조한 OpenVEX v0.2.0 원문은 제품·취약점·상태와 시점을 연결한다. 확인한 커밋은 61b5f885d0f4…이며, 다음 네 상태를 구분한다.

OpenVEX 상태 읽을 의미 배포 담당자가 이어서 확인할 것
affected 해당 제품이 영향을 받음 수정·완화 방법과 우리 서비스의 노출·대응 시급성
not_affected 해당 제품은 그 취약점의 영향 없음으로 판단됨 판단 근거, 대상 일치, 현재도 성립하는 조건
fixed 해당 제품 버전에 수정이 포함됨 실제 교체한 버전·아티팩트가 그 대상인지
under_investigation 영향 여부를 아직 모름 다음 확인 책임자·시점, 그동안 적용할 통제

이 상태가 곧 조직의 배포 승인 상태는 아니다. 특히 조사 중을 영향 없음으로 취급하면 미확인 자료가 자동 예외가 된다. VEX를 받지 못한 상태 역시 취약하다는 확정도, 안전하다는 확정도 아니다.

not_affected를 받았다면 근거를 읽는다. 취약한 구성품이 아예 없는 경우, 구성품은 있지만 취약한 코드가 빠진 경우, 취약한 코드가 제품의 실행 경로에 없는 경우는 서로 다른 설명이다. 테스트 몇 번에서 실행되지 않았다는 관측만으로 모든 경로에서 실행될 수 없다고 결론 내릴 수는 없다. 정적 분석·빌드 설정·제품 구조 등 해당 주장에 맞는 증거가 필요하다.

OpenVEX 문서는 작성자·시점·문서 버전도 다룬다. 이를 사용하는 팀은 누구의 평가를 받아들일지, 정정된 문서를 어떻게 받을지 정해야 한다. 오래된 문서의 날짜만 새로 붙이는 것은 재평가가 아니다. 같은 제품을 유지하더라도 새로운 취약점 정보나 기존 판단의 오류가 나오면 판단을 바꿀 수 있어야 한다.

가상 릴리스 접수: 무엇이 달라지면 결론을 바꿀까

앞의 문서 변환 서비스로 돌아가자. 설명을 위해 doc-codec 4.2의 취약점 DEMO-ADV-01은 외부 입력이 특정 구형 변환기를 호출할 때 영향을 준다고 가정한다. 실제 CVE 번호나 실제 라이브러리의 취약점이 아니다.

배포 후보 A는 그 구형 변환기를 빌드에서 제외했다. 후보 B는 같은 제품 버전 2.4.1이지만 변환기를 포함한 재빌드다. A의 digest를 H_A, B의 digest를 H_B로 부른다. 공급자는 A에 대해 취약 코드가 포함되지 않았다는 평가와 근거를 제공했다고 가정한다.

받은 자료와 현재 상황 이 글의 판단 다음 행동
A의 SBOM·검증된 provenance·영향 없음 근거가 모두 A를 가리킴 이 취약점에 대한 예외를 검토할 근거가 있음 조직 정책에 따라 승인 주체·재검토 조건을 남김
실제 배포 후보는 B인데 자료는 A의 것 대상 불일치, A의 판단을 B에 적용할 수 없음 B의 구성과 영향 자료를 확보할 때까지 새 배포 승인 보류
B의 provenance는 유효하지만 영향은 조사 중 빌드 경로 확인과 취약점 판단이 서로 다른 상태 영향 조사를 계속하고 노출·중요도에 따른 임시 통제 결정
B에서 기능을 꺼 두었으니 안전하다고 주장하지만 실행 경로 근거는 없음 설정 비활성화만으로 영향 없음 확정 불가 우회 호출·다른 입력 경로·설정 변경 가능성 조사
수정한 후보 C로 교체했고, 수정 평가의 대상도 C임 이 취약점의 해결 여부를 확인할 단계 실제 배포 인스턴스가 C인지 확인하고 다른 경보는 별도 유지

표의 첫 행도 “A는 모든 면에서 안전하다”는 판정이 아니다. 다루는 것은 DEMO-ADV-01 하나다. 다른 구성품의 취약점, 악성 로직, 운영 권한 문제는 이 근거로 해결되지 않는다. 또한 표는 새 배포 승인의 검토 흐름이다. 이미 운영 중인 서비스를 즉시 중단할지는 공격 정황, 피해 범위, 가용성, 완화 가능성을 함께 보는 사고 대응 판단이다.

가장 주의할 반례는 바이너리가 같아도 적용 조건은 바뀔 수 있다는 점이다. B의 파일을 그대로 두고 설정만 바꿔 구형 변환 기능을 외부에 노출했다고 하자. digest는 그대로지만 “외부 입력이 이 경로에 도달하지 않는다”는 운영 판단은 깨질 수 있다. 제품 자체의 VEX와 운영 환경에서 적용한 통제를 별도로 기록해야 이 차이를 놓치지 않는다.

따라서 예외의 식별 단위를 단순히 라이브러리 이름 + 취약점 번호로 두는 것은 거칠다. 이 사례에서는 최소한 제품·배포 아티팩트·취약점·적용 조건·근거 버전을 함께 묶는 편이 낫다. 이는 편집상의 설계 제안이며 VEX의 필수 필드 목록이나 새로운 표준은 아니다.

다음 담당자가 다시 판단할 수 있게 남긴다

다음 양식은 티켓이나 릴리스 검토 문서에 복사해 쓸 수 있다. 표준 SBOM/VEX 문법이 아니며, 자동 검사기에 넣는 설정도 아니다. 실제 값은 내부 시스템에 보관하고 토큰·고객 자료를 붙이지 않는다.

배포 대상: 제품 / 버전 / 플랫폼 / 아티팩트 digest
조사 중인 취약점: 식별자 / 참조 공지 / 해당 구성품

SBOM: 문서 ID·버전 / 생성 대상·시점 / 알려진 공백
빌드 증거: 대상 일치 / 서명·빌더 신뢰 / 기대 소스·입력 대조
영향 평가: 작성자 / 대상 제품 / 상태 / 판단 근거 / 갱신 시점
운영 조건: 노출 경로 / 적용한 통제 / 확인하지 못한 범위

결정: 새 배포 보류 / 추가 조사 / 정책상 승인·예외
결정 근거: 어떤 증거로 어떤 질문에 답했는가
후속 책임: 담당자 / 다음 확인일 / 예외 만료일
재검토 조건: 빌드·설정·노출 변경 / 정정된 평가 / 새 공격 정보
배포 후 확인: 실제 실행 중인 대상이 검토한 대상과 같은가

예를 들어 후보 A의 접수 기록이라면 “DEMO-ADV-01, 취약 코드 제외 근거를 확인하여 이 항목에 한해 정책상 예외 검토”라고 좁혀 쓴다. “스캔 통과”라고만 남기면 무엇을 제외했고 왜 제외했는지 다음 담당자가 복원할 수 없다. 재빌드 B가 들어왔을 때 이전 결정을 그대로 복사하기도 쉬워진다.

처음부터 모든 공급망 도구를 붙일 필요는 없다. 팀에 부족한 답부터 구하면 된다. 납품 파일과 증거를 연결할 수 없다면 식별·검증 경로를 먼저 정리하고, 구성 목록만 있다면 취약점 공지와 영향 평가를 연결한다. 예외가 계속 누적된다면 만료·재검토 책임을 먼저 정한다. 이런 운영 비용을 맡을 사람이 없는 상태에서 JSON 문서만 더 수집해도 배포 판단은 나아지기 어렵다.

실행 중 외부 코드에 어떤 권한을 줄지 고민한다면 Wasm과 컨테이너의 실행 경계를 이어 읽을 수 있다. AI 도구 서버를 연결하는 상황에서는 MCP와 API의 인증·업무 책임이 다음 질문에 가깝다. 공급망 검토는 받은 소프트웨어의 증거를 다루고, 이 글들은 실행 후 허용할 행동을 다룬다.

다음 릴리스에서 접수표를 다시 쓸 계획이라면 글 상단의 저장 기능을 이용할 수 있다. 관련 해설은 보안 주제 모음과 RSS에서도 이어 볼 수 있다.

다시 읽을 때의 기준
  • SBOM·provenance·VEX는 구성품, 빌드 경로, 취약점 영향이라는 서로 다른 질문에 답한다.
  • 서명 검증과 아티팩트 digest 일치, 승인된 빌더·소스·파라미터 대조를 함께 확인한다.
  • 목록에서 찾지 못함과 없음이 확인됨을 구분한다. 조사 중 상태도 영향 없음으로 바꾸지 않는다.
  • 영향 없음 판단은 제품·취약점·조건에 묶고, 빌드·설정·근거가 바뀌면 다시 검토한다.
SOURCES & CONTEXT

근거와 원자료

자료의 발행 시점과 이번 글에서 참고한 범위를 함께 기록합니다.

  1. The Minimum Elements for a Software Bill of Materials (SBOM) ↗NTIA · U.S. Department of Commerce · 2021

    2021-07-12 원문. Data Fields, Frequency, Depth, Known Unknowns의 구성·관계·누락 구분. 2026년 법규·조달 요건의 최신판이라고 주장하지 않음.

  2. SLSA v1.2 — Build: Provenance ↗SLSA · OpenSSF · v1.2 · Approved

    빌더·빌드 정의·산출물의 관계 및 resolvedDependencies의 best-effort 완전성. 규격 v1.2와 predicateType의 /v1을 혼동하지 않음. 취약점 부재나 실제 빌드 검증 성공을 뜻하지 않음.

  3. SLSA v1.2 — Build: Verifying artifacts ↗SLSA · OpenSSF · v1.2 · Approved

    How to verify와 Check expectations: 서명·신뢰 기준, subject digest, builder·canonical source·buildType·externalParameters 대조. 실제 서명 검증기를 실행하지 않았음.

  4. OpenVEX Specification v0.2.0 ↗OpenVEX project · v0.2.0 · commit 61b5f885d0f4

    2026-09-09 커밋. 제품·취약점·시점·상태, 작성자·문서 버전, not_affected의 근거와 네 상태의 의미. 실제 제품에 대한 영향 평가는 수행하지 않음.

  5. Vulnerability Exploitability eXchange (VEX) ↗OWASP CycloneDX · 상시 갱신 문서

    CycloneDX에서도 VEX를 표현한다는 범위에 사용. 본문의 상태 이름과 근거 설명은 별도로 고정한 OpenVEX v0.2.0에 따름. CycloneDX 스키마 실행 예제 아님.

갱신 기록

첫 원고. NTIA·SLSA v1.2·OpenVEX v0.2.0 원문을 대조하고 가상 릴리스의 판단 사례와 접수표를 구성했다. 실제 스캔·서명 검증·공격·배포는 실행하지 않았다.

오류를 발견했다면 →
S
Starhunter

테크독해 운영·편집. AI·IT의 개념과 기술을 연결해 읽습니다.