모든 글

읽는 데 9분

CI/CD 빌드 증거를 공개 타임스탬프에 어떻게 고정합니까?

CI/CD 파이프라인은 빌드 산출물, SBOM, 로그, 릴리스 매니페스트를 해시하고, 이를 하나의 Merkle 루트로 묶어 단일 Label 309 증명으로 게시할 수 있습니다. 이후 감사를 위한 독립적인 공개 시간 앵커가 됩니다.

가능합니다. CI/CD 파이프라인은 무엇을 언제 빌드했는지에 대한 증명을 게시할 수 있습니다. 핵심 패턴은 중요한 산출물(아티팩트, SBOM, 로그, 릴리스 매니페스트)을 해시하고, 그 해시들을 하나의 Merkle 루트로 모은 다음, 빌드·릴리스·기간 단위로 단일 Label 309 레코드를 게시하는 것입니다. 이후 누구나 특정 아티팩트나 매니페스트가 그 커밋된 배치에 포함되어 있었다는 것, 그리고 그 배치가 공개 블록 타임 시점 또는 그 이전에 존재했다는 것을 증명할 수 있습니다.

이는 SLSA, Sigstore, GitHub Artifact Attestations, in-toto를 대체하지 않습니다. 오히려 이들 중 어느 것도 직접 제공하지 않는 한 가지, 즉 어떤 벤더도 통제하지 않는 독립적이고 공개적이며 발행자 비종속적인 시간 앵커로 이들을 보완합니다.

CI/CD 파이프라인은 실제로 무엇을 증명해야 합니까?

1년 뒤에 제출해야 할 수도 있는 증거에서 출발하십시오.

CI/CD 증명은 다음을 커밋할 수 있습니다.

  • 릴리스 아티팩트;
  • 컨테이너 이미지 다이제스트;
  • SBOM(소프트웨어 자재 명세서) 파일;
  • SLSA 출처 증명 어테스테이션;
  • in-toto 링크 메타데이터;
  • 빌드 로그;
  • 테스트 보고서;
  • 배포 매니페스트;
  • 변경 이력 스냅샷;
  • 소스 커밋 참조;
  • 의존성 잠금 파일;
  • 서명된 체크섬;
  • 릴리스 노트.

존재한다는 이유만으로 모든 것을 해시하지는 마십시오. 보안, 감사, 사고 대응, 고객 신뢰, 릴리스 무결성에 중요한 아티팩트를 해시하십시오.

좋은 증명은 미래의 구체적인 질문 하나에 답합니다. "이 정확한 아티팩트나 매니페스트가 그 시점에 우리가 커밋한 릴리스 증거의 일부였습니까?"

Merkle 배칭 패턴은 어떻게 동작합니까?

단일 아티팩트라면 해시 증명 하나로 충분합니다.

릴리스에는 보통 여러 아티팩트가 들어 있는데, 각각을 개별 트랜잭션으로 게시하는 것은 낭비입니다. Merkle 루트가 이를 해결합니다. 모든 증거 항목을 해시하여 리프로 만들고, 순서가 정해진 리프들을 32바이트 루트 하나로 모은 뒤, 그 루트만 게시합니다. 릴리스 전체를 포괄하는 단일 온체인 레코드가 됩니다.

파이프라인은 다음 순서로 진행됩니다.

  1. 아티팩트를 빌드합니다.
  2. SBOM, 어테스테이션, 로그, 매니페스트를 생성하거나 수집합니다.
  3. 각 증거 항목을 해시하여 리프로 만듭니다.
  4. 순서가 정해진 리프 목록을 구성합니다.
  5. Merkle 트리를 만들고 루트를 계산합니다.
  6. 루트를 담은 Label 309 레코드 하나를 게시합니다.
  7. 리프 목록과 포함 증명을 릴리스 증거와 함께 저장합니다.

이후 검증기는 파일 하나 또는 다이제스트 하나를 받아 그 포함 증명을 확인하고, 해당 항목이 Label 309 레코드 안의 루트에 속하는지 확인합니다. 포함 증명은 배치 크기의 로그만큼만 커지므로, 수천 개의 리프를 포괄하는 루트라도 밀리초 단위로 검증됩니다. 게이트웨이도 네트워크도 없이 완전히 오프라인으로 말입니다. 전체 동작 원리는 수천 개 파일을 레코드 하나로를 참고하십시오.

기존 어테스테이션에 그냥 의존하면 안 됩니까?

기존 어테스테이션을 그대로 쓰되, 거기에 앵커를 더하십시오.

SLSA 출처 증명은 소프트웨어 아티팩트가 어디서, 언제, 어떻게 생성되었는지를 기술합니다. GitHub Artifact Attestations는 바이너리나 컨테이너 이미지 같은 아티팩트의 빌드 출처를 확립합니다. Sigstore는 서명된 공급망 메타데이터를 Rekor라는 공개 추가 전용 투명성 로그에 기록합니다. in-toto는 공급망의 각 단계가 계획대로, 올바른 주체에 의해, 올바른 입력으로 수행되었는지 검증하는 프레임워크입니다.

이들 각각은 실제 문제를 해결합니다. Label 309는 다른 문제를 해결합니다. 특정 증거 집합이 특정 공개 시점까지 존재했다는, Cardano에 고정되고 독립적으로 검증 가능한 증명을 게시하는 것입니다. 견고한 파이프라인은 "어테스테이션이냐 존재 증명이냐"를 두고 고르지 않습니다. 둘 다 씁니다.

  • 빌드 출처에는 SLSA 또는 GitHub 어테스테이션;
  • 서명 및 투명성 로그 워크플로에는 Sigstore;
  • 공급망 단계 검증에는 in-toto;
  • 증거 집합 전체에 대한 공개 시간 앵커에는 Label 309.

Label 309는 그 위에 무엇을 더합니까?

Cardano에 남는 내구성 있는 공개 커밋먼트를 더합니다.

그 커밋먼트는 단일 릴리스 매니페스트를 포괄할 수도 있고, 여러 증거 항목에 대한 Merkle 루트를 포괄할 수도 있습니다. 프로젝트나 회사 신원으로 서명할 수도 있습니다. 그리고 트랜잭션 메타데이터와 공개 Cardano 익스플로러만으로 검증할 수 있습니다. 계정도, 로그인도, 원래 CI 제공업체의 대시보드가 계속 온라인 상태로 남아 있어야 한다는 의존성도 없습니다.

이 독립성은 어떤 후속 사건 이전에 증거가 존재했음을 팀이 증명해야 할 때 가장 큰 의미를 가집니다.

  • 취약점 공개;
  • 보안 사고;
  • 고객 보안 점검;
  • 조달 감사;
  • 컴플라이언스 마감;
  • 릴리스 분쟁;
  • 공급망 조사.

이 증명은 관련된 누구도 몰래 옮길 수 없는 앵커를 타임라인에 제공합니다.

감사인은 무엇을 검증하게 됩니까?

감사인은 단일 아티팩트에서 출발해 온체인 레코드까지 그 연결 고리를 따라갈 수 있어야 합니다.

  1. 검토 대상 아티팩트나 SBOM을 준비합니다.
  2. 그 해시를 계산합니다.
  3. 포함 증명을 릴리스 Merkle 루트와 대조해 확인합니다.
  4. 그 루트가 Label 309 레코드에 나타나는지 확인합니다.
  5. Cardano 트랜잭션을 조회하고 그 블록 타임을 읽습니다.
  6. 레코드 서명이 있다면 검증합니다.
  7. 주변의 출처 증명이나 어테스테이션은 그 자체의 규칙에 따라 확인합니다.

이렇게 하면 두 가지 질문이 깔끔하게 분리됩니다. Label 309 증명은 이 증거가 이 공개 시점까지 커밋되었는가? 에 답합니다. SLSA, Sigstore, GitHub, in-toto 계층은 이 증거가 아티팩트의 빌드·서명·배포 방식에 대해 무엇을 말하는가? 에 답합니다. 어느 쪽도 다른 쪽의 일을 대신하려 들지 않습니다.

릴리스 매니페스트에는 무엇이 들어갑니까?

릴리스 매니페스트는 평범하고 빠짐없어야 합니다. 다음을 포함할 수 있습니다.

  • 릴리스 이름과 버전;
  • 저장소 URL;
  • 소스 커밋;
  • 빌드 워크플로 식별자;
  • 빌드 호출 ID;
  • 아티팩트 이름과 다이제스트;
  • 컨테이너 이미지 다이제스트;
  • SBOM 파일 다이제스트;
  • 어테스테이션 파일 다이제스트;
  • 테스트 보고서 다이제스트;
  • 빌드 로그 다이제스트;
  • CI 시스템이 보고한 타임스탬프;
  • 게시 이후 추가되는 Label 309 트랜잭션 참조.

매니페스트 자체도 해시하여 리프로 포함할 수 있습니다. 또한 매니페스트는 배치 안의 다른 모든 리프를 설명하는 사람이 읽을 수 있는 색인 역할도 겸합니다. 형식은 안정적으로 유지하십시오. 증거 구조가 릴리스마다 예측 가능할 때 증명을 더 쉽게 검증할 수 있습니다.

파이프라인이 레코드에 서명해야 합니까?

대개 그렇습니다.

Merkle 루트는 어떤 목록이 커밋되었음을 증명합니다. 서명은 여기에 더해, 프로젝트·회사·릴리스 시스템·승인된 신원이 그 커밋먼트를 보증했다는 것을 보여줍니다. Label 309에서 이는 선택적인 레코드 수준 서명입니다. 존재 클레임을 검증하는 데 작성자 서명이 반드시 필요한 것은 아니지만, 책임 소재를 분명히 하고 싶을 때 사용할 수 있습니다.

서명 키는 신중하게 관리하십시오. 수명이 긴 신원 시드를 아무 CI 러너에나 흩뿌리지 마십시오. 위협 모델에 따라 전용 릴리스 신원, 통제된 서명 서비스, 하드웨어 기반 워크플로, 또는 접근 제어가 엄격한 자체 호스팅 러너를 사용하십시오. 오픈소스 cardanowall CLI는 바로 이 용도로 만들어졌습니다. 게이트웨이에 종속되지 않고 원시 시드를 우선하므로, 중간에 웹사이트를 끼우지 않고도 자동화에 그대로 들어맞습니다. 처음부터 끝까지 흐름은 자동화에서 CLI 사용하기를 참고하십시오.

서명은 책임 소재를 더해 줍니다. 그러나 서명 자체가 취약한 빌드 파이프라인을 안전하게 만들지는 못합니다.

리프 목록은 어디에 두어야 합니까?

릴리스 증거와 함께 저장하십시오.

리프 목록과 포함 증명이 있어야 나중에 개별 항목을 증명할 수 있습니다. 루트만 게시하고 리프 목록을 잃어버리면, 어떤 목록이 존재했다는 것은 여전히 증명할 수 있지만, 특정 아티팩트가 그 안에 있었다는 것은 더 이상 증명하지 못할 수 있습니다.

좋은 저장 방식은 워크플로에 따라 다릅니다.

  • 릴리스 아카이브에 첨부합니다;
  • 아티팩트 저장소에 저장합니다;
  • 내부 증거 버킷에 보관합니다;
  • 기밀 증거라면 암호화된 콘텐츠로 봉인합니다;
  • 공개해도 안전한 경우 콘텐츠 주소 지정 스토리지를 통해 게시합니다.

루트는 앵커입니다. 리프 목록은 지도입니다.

파이프라인은 얼마나 자주 게시해야 합니까?

증명 주기를 릴리스 주기에 맞추십시오. 흔한 선택지는 다음과 같습니다.

  • 릴리스당 증명 하나;
  • 빌드당 증명 하나;
  • 배포당 증명 하나;
  • 연속 로그에 대해 하루당 증명 하나;
  • 보안상 중요한 이벤트당 증명 하나.

너무 드물게 게시하면 타임라인이 약해지고, 너무 자주 게시하면 비용과 운영상의 잡음이 늘어납니다. Merkle 배칭을 쓰면 비즈니스 질문에 맞는 주기를 고를 수 있습니다. 고객이 "버전 2.3.1에 정확히 무엇이 출시되었나요?"라고 묻는다면 릴리스당 증명 하나로 충분합니다. 규제 기관이나 감사인이 모니터링이 연속적이었는지를 묻는다면 일별 또는 시간별 커밋먼트가 더 낫습니다.

게시에는 비용이 듭니다. 게이트웨이가 실제 Cardano 트랜잭션 수수료와 스토리지 비용을 지불하기 때문입니다. 따라서 주기는 비용 대 증거의 실질적인 절충이지, 공짜로 돌릴 수 있는 다이얼이 아닙니다.

CI/CD 증명이 증명하지 못하는 것은 무엇입니까?

빌드가 안전했다는 것은 증명하지 못합니다.

존재 증명은 아티팩트, SBOM, 로그, 매니페스트가 공개 시점까지 존재했다는 것, 그 항목이 커밋된 배치에 포함되었다는 것, 그리고 어떤 키가 레코드에 서명했다는 것을 보여줄 수 있습니다. 증명이 보장하는 것은 이것이 전부입니다.

소스 코드가 안전했다는 것은 증명하지 못합니다. 러너가 침해되지 않았다는 것도 증명하지 못합니다. 의존성에 취약점이 없었다는 것도 증명하지 못합니다. SBOM이 완전하다는 것도 증명하지 못합니다. 그리고 어테스테이션 자체의 검증 규칙을 통과하지 않는 한, 그 어테스테이션이 신뢰할 만하다는 것도 증명하지 못합니다. Label 309가 공급망 보안 도구를 대체하는 대신 그 옆에 자리하는 이유가 바로 이것입니다. 일반적인 한계는 증명이 증명하지 못하는 것을 참고하십시오.

처음 구현하기에 좋은 방법은 무엇입니까?

릴리스 증명부터 시작하십시오. 릴리스마다 다음을 수행합니다.

  1. 평소의 아티팩트를 생성합니다.
  2. SBOM과 어테스테이션을 생성하거나 수집합니다.
  3. 릴리스 매니페스트를 작성합니다.
  4. 모든 증거 파일을 해시하여 리프로 만듭니다.
  5. Merkle 루트를 만듭니다.
  6. 서명된 Label 309 레코드를 게시합니다.
  7. 트랜잭션 참조를 릴리스 노트에 저장합니다.
  8. 매니페스트, 리프 목록, 포함 증명을 릴리스와 함께 저장합니다.

이렇게 하면 첫날부터 빌드 시스템을 다시 설계하지 않고도 실용적인 증거 추적 경로를 확보할 수 있습니다. 거기서부터 일별 로그, 배포 매니페스트, 더 대용량의 자동화로 확장해 나가십시오.

핵심 요약

CI/CD 증명은 릴리스 증거에 대한 타임스탬프가 찍힌 커밋먼트입니다.

중요한 아티팩트, SBOM, 로그, 어테스테이션, 매니페스트를 해시하십시오. 이를 하나의 Merkle 루트로 묶으십시오. 그 루트를 Label 309 레코드로 게시하십시오. 프로젝트나 회사 신원이 그것을 보증하기를 원한다면 레코드에 서명하십시오.

출처 증명과 공급망 메타데이터에는 SLSA, Sigstore, GitHub Artifact Attestations, in-toto를 그대로 유지하십시오. 그리고 증거 집합 전체를 어떤 벤더도 옮길 수 없는 한 순간에 묶어 주는 독립적인 공개 시간 앵커로 Label 309를 더하십시오.

더 읽을거리

ci-cdmerklesoftware-supply-chain