재현 가능한 빌드
재현 가능한 빌드는 같은 소스 코드를 같은 빌드 환경과 같은 빌드 지침으로 빌드하면 누가 하든 비트 단위로 동일한 결과물이 나오는 빌드입니다.
최종 업데이트: 2026년 11월 11일
재현 가능한 빌드는 같은 소스 코드를 같은 빌드 환경과 같은 빌드 지침으로 빌드하면 누가 하든 비트 단위로 동일한 결과물이 나오는 빌드입니다. 이는 Reproducible Builds 프로젝트의 정의를 따른 것입니다. 여기서 결과물은 실행 파일, 배포 패키지, 컨테이너나 파일 시스템 이미지처럼 빌드가 만들어야 하는 아티팩트를 뜻합니다. 로그는 포함되지 않습니다. "다시 빌드된다"는 것과는 다르며, 재현 가능하다는 것은 바이트가 일치한다는 뜻입니다.
대부분의 빌드가 재현 가능하지 않은 이유
- 빌드 시점의 종속성 해석. 잠금 파일이 없으면 패키지 관리자는 빌드가 실행될 때 버전을 고릅니다. PyPI 해석은 응답이 도착하는 순서에 따라 결과가 달라질 수 있고, 버전 범위는 새 릴리스가 나오면 움직이며,
latest같은 가변 태그는 다른 것을 가리키게 됩니다. - 환경. 타임스탬프, 파일 경로, 로캘, 호스트 자체의 도구가 아티팩트에 들어갑니다.
- 무작위성. 빌드 단계에서 ID를 생성하거나, 해시 순으로 파일을 정렬하거나, 매번 다른 순서로 병렬 작업을 실행할 수 있습니다.
따라서 같은 커밋을 연달아 두 번 빌드해도 같은 결과나 같은 SBOM이 나온다는 보장은 없습니다. 잠금 파일에 없는 코드를 다운로드하는 빌드, 즉 숨은 종속성이 있는 빌드는 상황을 더 악화시킵니다.
팀이 빌드를 재현 가능하게 만드는 방법
- 베이스 이미지는 다이제스트로, 도구는 버전으로 고정하는 등 모든 입력을 고정하고 잠급니다(잠금 파일 참고).
- 시계 대신 고정된 시각을 사용합니다.
SOURCE_DATE_EPOCH는 빌드 도구가 현재 시각 대신 사용하는 Unix 타임스탬프를 담은 표준 환경 변수입니다. - 빌드 경로를 제거하거나 정규화하고, 파일 목록을 정렬하고, 로캘을 고정합니다.
- 툴체인 자체도 고정된 밀폐 환경에서 빌드합니다. Nix가 그 방법 중 하나입니다.
- 검증합니다. 같은 커밋을 다른 머신, 다른 경로, 다른 날에 서로 독립적으로 두 번 빌드하고 출력을 비교합니다. 해시가 다르면 diffoscope가 무엇이 달라졌는지 정확히 보여 줍니다.
Yocto Project는 재현성이 가정할 것이 아니라 검증해야 할 속성임을 보여 줍니다. 이 프로젝트의 문서에 따르면 프로젝트의 빌드는 릴리스 3.1부터 "타임스탬프를 포함한 바이너리 수준까지" 재현 가능하며, 완전한 재현성을 보장하는 것은 BitBake와 OpenEmbedded-Core뿐이고, "다른 레이어를 추가하는 순간 이 보증은 무효가 된다"고 합니다. 프로젝트는 이를 oe-selftest로 검증합니다.
재현 가능한 빌드와 SBOM
모든 빌드가 재현 가능하다면 오래된 릴리스를 나중에 다시 빌드해 SBOM을 생성할 수 있습니다. 하지만 대부분은 그렇지 않으므로, 다시 빌드하거나 오늘 소스 코드를 스캔하면 출시한 빌드가 아니라 비슷한 빌드를 설명하게 됩니다. 운영 환경에 무엇이 있는지 보여 주는 SBOM은 해당 릴리스를 만든 CI 빌드에서 기록한 SBOM입니다.
재현 가능한 빌드라도 그 기록이 필요 없어지지는 않습니다. 해시가 일치하면 두 빌드가 같은 결과물을 만들었다는 것은 증명되지만, 무엇이 들어갔는지는 나열하지 않습니다. 여전히 인벤토리와, 그 SBOM 완전성에 대한 정직한 표기가 필요합니다. 더 자세한 논의는 CI가 공급망 보안의 자리인 이유와 SBOM 모범 사례에 있습니다.
SLSA는 재현성을 빌드가 주장한 대로 수행되었는지 검증하는 방법 중 하나로 다룹니다.
재현성은 Nix, Yocto, Debian의 도구 같은 수단으로 빌드 시스템에서 달성하는 것입니다. CRACI는 빌드를 재현 가능하게 만들지 않습니다. CRACI는 빌드가 실행되는 동안 각 빌드의 SBOM을 기록하므로, 출시한 것의 기록이 재빌드에 좌우되지 않습니다. 빌드 시점 SBOM을 참고하세요.