-
[GitHub Actions][공급망보안] Docker 이미지를 여러 registry에 publish할 때 multi-registry digest drift와 단일 registry attestation 검증을 어떤 순서로 다시 나누나기타개발지식/풀스택개발 2026. 8. 16. 20:15
IT 리서치 노트
[GitHub Actions][공급망보안] Docker 이미지를 여러 registry에 publish할 때 multi-registry digest drift와 단일 registry attestation 검증을 어떤 순서로 다시 나누나
GitHub Actions로 같은 Docker 이미지를 여러 registry에 publish하기 시작하면 digest와 attestation 메모가 빠르게 엉킨다. 2026년 8월 16일 기준 GitHub 공식 문서를 다시 보면 한 workflow로 여러 registry에 이미지를 publish할 수 있고, container image attestation 검증은
oci://가 붙은 이미지 FQDN으로 수행해야 하며, linked artifacts 업로드는push-to-registry: true같은 별도 조건을 가진다. 여기에 Docker 문서는 manifest list digest와 platform별 digest를 구분해 설명한다. 이 글은 multi-registry digest drift와 단일 registry attestation verify mismatch를 어떤 순서로 다시 나누는 편이 운영 기록을 덜 섞이게 만드는지 정리한 것이다.1. 개요
결론부터 말하면 multi-registry publish 사고 메모는
어느 registry에 어떤 ref를 push했는지,어느 registry FQDN으로 attestation을 verify했는지,manifest list digest인지 platform digest인지를 따로 적어야 한다. 태그가 같다는 이유로 digest와 attestation verify를 한 증상처럼 적으면 원인 분리가 늦어진다.GitHub 문서는 한 workflow로 여러 registry에 이미지를 publish할 수 있다고 설명하고, attestation verify는 이미지 FQDN으로 실행하라고 설명한다. Docker 문서는 manifest list digest와 platform별 digest를 따로 설명한다. 이 셋을 같이 보면 registry별 publish와 registry별 verify는 같은 단계가 아니라는 점이 분명해진다.
2. 어디서 실제로 막히는가
현장에서 자주 생기는 실수는 세 가지다. 첫째, Docker Hub와 GHCR에 같은 태그를 push한 뒤 한쪽 registry에서 얻은 digest를 다른 쪽에도 그대로 적는다. 둘째, attestation verify를 한 registry에서만 통과시켜 놓고 "이미지 전체가 검증됐다"고 기록한다. 셋째, multi-arch 이미지의 manifest list digest와 platform별 digest를 구분하지 않는다.
GitHub publish 가이드는 하나의 workflow가 여러 registry에 push할 수 있다고 보여 주고, artifact attestation 문서는 컨테이너 이미지 verify가
oci://registry/repo:tag형식의 FQDN을 받는다고 설명한다. Docker digest 문서는 multi-platform 이미지가 하나의 manifest list digest와 여러 platform digest를 가진다고 설명한다. 따라서 "태그는 같다"는 사실만으로 digest와 verify 결과를 하나로 묶으면 안 된다.이미 Docker 기본 provenance와 GitHub attestation 비교 글이 증거 층 자체를 분리했다면, 이번 글은 거기에 registry 축을 추가한 운영 메모다. 같은 attestation이더라도 어느 registry ref를 검증했는지 없으면 실제 배포 대상과 verify 대상이 엇갈린다.
- 증상: 같은 태그인데 registry별 digest 메모가 서로 다르거나 빠져 있다.
- 실패: 한 registry에서 attestation verify가 통과하면 다른 registry도 같은 결과라고 가정한다.
- 막힘: manifest list digest와 platform별 digest를 구분하지 않는다.
- 누락: verify 대상 registry FQDN과 linked artifacts 조건을 release note에 남기지 않는다.
보이는 현상 먼저 볼 층 판단 기준 registry별 digest가 다르게 보인다 digest 층 manifest list인지 platform digest인지 먼저 본다 verify가 한 registry에서만 통과한다 attestation verify 층 oci:// FQDN이 정확한지 다시 본다 linked artifacts는 있는데 release note가 비어 있다 storage record 층 push-to-registry와 verify 대상 ref를 따로 적는다 3. 실무에서 적용하는 순서
가장 실용적인 순서는 다섯 단계다. 1단계에서 실제 push 대상 registry ref를 모두 적는다. 2단계에서 registry별 digest를 inspect 결과로 적는다. 3단계에서 manifest list digest와 platform digest를 분리한다. 4단계에서 attestation verify를 수행한 registry FQDN을 적는다. 5단계에서 linked artifacts와 verify 결과를 같은 시간축에 붙인다.
- registry별 이미지 ref를 먼저 고정한다.
- registry별 digest를 따로 수집한다.
- manifest list와 platform digest를 같은 칸에 쓰지 않는다.
- attestation verify는 oci:// FQDN 기준으로 기록한다.
- linked artifacts와 verify 시각을 마지막에 붙인다.
실제로는 workflow 파일을 열고, tags 목록을 확인하고, registry별로 로그인 단계를 확인하고, build-push-action 출력 digest를 저장하고,
gh attestation verify명령을 실행하고, 어떤oci://FQDN을 입력했는지 기록하고, linked artifacts 업로드 여부를 조회하고, release note에 최종 검증 registry를 저장하는 흐름이 가장 짧다. 이 순서가 있어야 나중에 "verify는 통과했는데 배포 대상 digest가 왜 다르지" 같은 질문을 빠르게 구분할 수 있다.또 Docker attestation 문서는 attestation이 image index에 manifest 형태로 붙는다고 설명한다. 그래서 multi-arch 이미지에서는 digest 메모도 더 조심해야 한다. platform별 manifest가 다른지, image index 수준이 같은지, verify는 어느 ref를 대상으로 했는지를 분리해 두어야 공급망 증거가 흔들리지 않는다.
같은 공급망 흐름에서 build input 쪽을 더 좁혀 보고 싶다면 Docker build context leak과 secret mount 분기 글을 같이 보는 편이 좋다. publish target 문제와 build input 문제는 서로 다른 계층이다.
4. 공식 문서와 예시 화면으로 확인하기
첫 공식 화면은 GitHub의 Docker publish 가이드다. 하나의 workflow로 단일 registry 또는 여러 registry에 이미지를 올릴 수 있다는 설명이 이번 triage의 출발점이다.
즉 multi-registry publish 자체는 비정상 신호가 아니다. 문제는 어느 registry의 digest를 기준 삼아 attestation을 검증했는지, 그리고 그 결과를 다른 registry에도 그대로 일반화했는지다.
두 번째 자료는 GitHub artifact attestations 검증 문서다. 컨테이너 이미지는 바이너리 파일 경로가 아니라
oci://가 붙은 이미지 FQDN으로 검증해야 한다는 점이 핵심이다.그래서 attestation verify 로그에는 반드시 어떤 registry FQDN으로 검증했는지 남겨야 한다. 같은 태그여도 registry가 달라지면 검증 대상 FQDN도 달라진다.
세 번째 공식 화면은 Docker의 digest 설명이다. Docker는 manifest list digest와 platform별 digest를 구분해 설명하므로, 태그 하나만으로 단일 digest라고 생각하면 안 된다.
이 구분 덕분에 multi-registry drift 메모도 더 정확해진다. 지금 바뀐 것이 registry 간 manifest list digest인지, 특정 플랫폼 manifest인지, 아니면 attestation storage record인지 먼저 갈라야 한다.
실무에서는 같은 이미지를 Docker Hub와 GHCR에 함께 밀어 넣고, 나중에는 어느 registry에서 검증했는지 메모가 빠지는 경우가 많다. 그래서 workflow 단계부터 registry별 태그와 verify 대상을 분리해 두는 편이 낫다.
이미 build-push-action provenance와 GitHub attestation 비교 글이 두 증거 층을 나눴다면, 이번 글은 그 다음 단계인 multi-registry publish 이후 registry별 digest와 verify 대상을 분리 기록하는 후속편이다.
마지막 자료는 digest drift와 attestation verify mismatch를 빠르게 가르는 표다. 같은 workflow라도 관찰 지점이 다르므로 한 증상을 다른 층에 덮어쓰면 안 된다.
이 표를 release note에 넣어 두면 post 344의 build context leak 메모와도 잘 이어진다. build input 문제와 publish target 문제와 attestation verify 문제를 한 줄로 쓰지 않는 것이 공급망 메모의 핵심이다.
5. 주의사항과 리스크
첫 번째 리스크는 태그 동일성을 digest 동일성으로 착각하는 것이다. Docker 문서는 manifest list digest와 platform digest를 다르게 설명한다. 두 번째 리스크는 한 registry에서 verify가 통과했으니 다른 registry도 같다고 일반화하는 것이다. GitHub verify는 registry FQDN을 받으므로 검증 대상 ref를 빠뜨리면 안 된다. 세 번째 리스크는 linked artifacts 업로드와 실제 배포 대상 registry를 같은 메모로 덮는 것이다.
- 같은 태그와 같은 digest는 같은 말이 아니다.
- registry별 verify 대상 ref를 빼면 attestation 메모가 무의미해진다.
- linked artifacts 존재만으로 배포 대상 검증이 끝난 것은 아니다.
6. 결론
Docker 이미지를 여러 registry에 publish할 때는 digest와 attestation verify를 registry 축으로 다시 나눠 적는 편이 맞다. registry별 ref, registry별 digest, verify 대상 FQDN, linked artifacts 시각이 분리돼 있어야 multi-registry drift와 verify mismatch를 빠르게 자를 수 있다.
요약하면 multi-registry publish는 정상 기능이고, 그 위에 붙는 digest 메모와 attestation verify가 어디를 가리키는지만 분명히 남기면 된다. 태그와 verify 성공 한 줄만으로 공급망 증거를 대체하면 안 된다.
7. 참고 링크
- https://docs.github.com/actions/guides/publishing-docker-images
- https://docs.github.com/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds
- https://docs.github.com/en/enterprise-cloud@latest/code-security/how-tos/secure-your-supply-chain/establish-provenance-and-integrity/upload-linked-artifacts
- https://docs.docker.com/dhi/explore/security-concepts/digests/
- https://docs.docker.com/build/metadata/attestations/
'기타개발지식 > 풀스택개발' 카테고리의 다른 글