Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
cosign — 컨테이너 및 바이너리를 위한 코드 서명 및 투명성 | Kitploit
도구/GitHubGitHub/sigstore/cosign
Authentication & AuthorizationContainer SecurityEncryption/Decryption ToolsCloud SecurityDevSecOpsSupply Chain SecurityContainer Security #15위DevSecOps #11위Supply Chain Security #6위
6.2k785831일 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
GitHubsigstore/cosign

cosign

컨테이너 및 바이너리를 위한 코드 서명 및 투명성

저장소 보기
<p align="center">
  <img style="max-width: 100%;width: 300px;" src="https://raw.githubusercontent.com/sigstore/community/main/artwork/cosign/horizontal/color/sigstore_cosign-horizontal-color.svg" alt="Cosign logo"/>
</p>

# cosign

[Sigstore](https://sigstore.dev/)를 사용하여 OCI 컨테이너(및 기타 아티팩트)에 서명합니다!

[![Go Report Card](https://goreportcard.com/badge/github.com/sigstore/cosign)](https://goreportcard.com/report/github.com/sigstore/cosign)
[![e2e-tests](https://github.com/sigstore/cosign/actions/workflows/e2e-tests.yml/badge.svg)](https://github.com/sigstore/cosign/actions/workflows/e2e-tests.yml)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5715/badge)](https://bestpractices.coreinfrastructure.org/projects/5715)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/sigstore/cosign/badge)](https://securityscorecards.dev/viewer/?uri=github.com/sigstore/cosign)

Cosign은 서명을 **보이지 않는 인프라**로 만드는 것을 목표로 합니다.

Cosign은 다음을 지원합니다:

* Sigstore 공익 Fulcio 인증 기관 및 Rekor 투명성 로그를 사용한 "키리스 서명" (기본값)
* 하드웨어 및 KMS 서명
* cosign이 생성한 암호화된 개인/공개 키 쌍을 사용한 서명
* OCI 레지스트리에서의 컨테이너 서명, 검증 및 저장.
* 자체 PKI 사용

## 정보

`Cosign`은 [`sigstore`](https://sigstore.dev) 프로젝트의 일부로 개발되었습니다.
우리는 또한 [slack 채널](https://sigstore.slack.com)을 사용합니다!
초대 링크는 [여기](https://join.slack.com/t/sigstore/shared_invite/zt-47srvpyn6-j8Ek5hGBwKN32IjLw8BvYA)를 클릭하세요.

## 설치

Homebrew, Arch, Nix, GitHub Action 및 Kubernetes 설치에 대해서는 [설치 문서](https://docs.sigstore.dev/cosign/system_config/installation/)를 참조하세요.

Linux, macOS 및 Windows 바이너리에 대해서는 [GitHub 릴리스 자산](https://github.com/sigstore/cosign/releases/latest)을 참조하세요.

:rotating_light: GCS 버킷에서 cosign 릴리스를 다운로드하는 경우 - 2023년 7월 31일 [지원 중단 공지](https://blog.sigstore.dev/cosign-releases-bucket-deprecation/)에 대한 자세한 정보를 확인하세요 :rotating_light:

## 개발자 설치

Go 1.22+가 있다면 개발 환경을 설정할 수 있습니다:

```shell
$ git clone https://github.com/sigstore/cosign
$ cd cosign
$ go install ./cmd/cosign
$ $(go env GOPATH)/bin/cosign
```

## 기여하기

`cosign`에 기여하는 데 관심이 있으시다면 [기여 문서](https://github.com/sigstore/cosign/blob/main/CONTRIBUTING.md)를 읽어 주세요.

향후 Cosign 개발은 [sigstore-go](https://github.com/sigstore/sigstore-go)를 기반으로 하는 다음 메이저 릴리스에 집중될 예정입니다. 메인테이너들은 sigstore-go 내의 기능 개발에 집중할 것입니다. sigstore-go에 대한 기여, 특히 자체 키(BYOK) 및 서명과 관련된 기여를 환영합니다. 좋은 첫 이슈(good first issues)는 [이슈 트래커](https://github.com/sigstore/sigstore-go/issues)를 참고해 주세요.

Cosign 2.x는 안정 릴리스이며 주기적인 기능 업데이트와 버그 수정이 계속 제공될 것입니다. 범위와 규모가 작은 PR이 빠르게 리뷰될 가능성이 높습니다.

API를 크게 수정하거나 중단시키는 PR은 허용되지 않습니다. 규모는 크지만 호환성을 깨뜨리는 변경을 도입하지 않는 PR은 허용될 수 있으나, sigstore-go의 PR보다 낮은 우선순위로 간주됩니다.

## Dockerfile

다음은 ghcr.io/sigstore/cosign/cosign 이미지를 통해 Dockerfile 내에서 cosign을 설치하고 사용하는 방법입니다:

```shell
FROM ghcr.io/sigstore/cosign/cosign:v2.4.1 as cosign-bin

# Source: https://github.com/chainguard-images/images/tree/main/images/static
FROM cgr.dev/chainguard/static:latest
COPY --from=cosign-bin /ko-app/cosign /usr/local/bin/cosign
ENTRYPOINT [ "cosign" ]
```

## 빠른 시작

이것은 다음 방법을 보여줍니다:
* 기본 신원 기반 "키리스 서명" 방식으로 컨테이너 이미지에 서명하기 ([자세한 내용은 문서를 참조하세요](https://docs.sigstore.dev/cosign/signing/overview/))
* 컨테이너 이미지 검증하기
* [Sigstore Cosign Quickstart](https://docs.sigstore.dev/quickstart/quickstart-cosign/)에서 더 넓은 키리스 블롭 서명/검증 흐름 살펴보기

### 컨테이너에 서명하고 레지스트리에 서명 저장하기

항상 태그(`:latest`)가 아닌 다이제스트(`@sha256:...`)를 기준으로 이미지에 서명해야 한다는 점에 유의하세요. 그렇지 않으면 의도하지 않은 것에 서명할 수 있습니다!

```shell
 cosign sign $IMAGE

Generating ephemeral keys...
Retrieving signed certificate...

	Note that there may be personally identifiable information associated with this signed artifact.
	This may include the email address associated with the account with which you authenticate.
	This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later.

By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs.
Are you sure you would like to continue? [y/N] y
Your browser will now be opened to:
https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=OrXitVKUZm2lEWHVt1oQWR4HZvn0rSlKhLcltglYxCY&code_challenge_method=S256&nonce=2KvOWeTFxYfxyzHtssvlIXmY6Jk&redirect_uri=http%3A%2F%2Flocalhost%3A57102%2Fauth%2Fcallback&response_type=code&scope=openid+email&state=2KvOWfbQJ1caqScgjwibzK2qJmb
Successfully verified SCT...
tlog entry created with index: 12086900
Pushing signature to: $IMAGE
```

Cosign은 OIDC를 통해 인증하라는 메시지를 표시하며, 여기서 이메일 주소로 로그인하게 됩니다.
내부적으로 cosign은 Fulcio 인증 기관에 코드 서명 인증서를 요청합니다.
인증서의 주체는 로그인한 이메일 주소와 일치합니다.
그런 다음 Cosign은 서명과 인증서를 Rekor 투명성 로그에 저장하고, 서명을 서명 중인 이미지와 함께 OCI 레지스트리에 업로드합니다.


### 컨테이너 검증

이미지를 검증하려면 `--certificate-identity` 및 `--certificate-oidc-issuer` 플래그를 통해 예상되는 인증서 주체와 인증서 발급자를 전달해야 합니다:

```
cosign verify $IMAGE --certificate-identity=$IDENTITY --certificate-oidc-issuer=$OIDC_ISSUER
```

인증서 ID 및 발급자 플래그에 정규식을 전달할 수도 있습니다: `--certificate-identity-regexp` 및 `--certificate-oidc-issuer-regexp`.

### 공개 키에 대해 컨테이너 검증

이 명령은 이미지에 대해 공개 키와 일치하는 *적어도 하나의* `cosign` 형식 서명이 발견되면 `0`을 반환합니다.
다른 서명 형식에 대한 정보와 주의사항은 아래의 자세한 사용법을 참조하세요.

유효한 페이로드는 모두 json 형식으로 stdout에 출력됩니다.
이러한 서명된 페이로드에는 컨테이너 이미지의 다이제스트가 포함되어 있으며, 이를 통해 이러한 "분리된" 서명이 올바른 이미지를 대상으로 하는지 확인할 수 있습니다.

```shell
$ cosign verify --key cosign.pub $IMAGE_URI:1h
The following checks were performed on these signatures:
  - The cosign claims were validated
  - The signatures were verified against the specified public key
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8"},"Type":"cosign container image signature"},"Optional":null}
```

### 에어갭 환경에서 컨테이너 검증하기

**참고:** 이 섹션은 최신 정보가 아닙니다.

**참고:** 대부분의 검증 워크플로는 TUF 저장소에서 서비스 키를 주기적으로 요청해야 합니다.
public-good 인스턴스를 사용하여 서명을 에어갭 검증하려면, 프로덕션
TUF 저장소에서 [trusted root](https://github.com/sigstore/root-signing/blob/main/targets/trusted_root.json) 파일을 가져와야 합니다. 이 파일의 내용은 예고 없이 변경될 수 있습니다. TUF를 사용하지 않으면, 이 파일의 에어갭 복사본을 최신 상태로 유지하기 위한 자체 메커니즘을 구축해야 합니다.

Cosign은 일반적으로 이미지 매니페스트의 어노테이션으로 배포되는 [bundle](https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md#properties)을 검증하여 완전한 오프라인 검증을 수행할 수 있습니다.
이 어노테이션이 존재하는 한, 오프라인 검증이 가능합니다.
이 bundle 어노테이션은 키리스 서명의 경우 항상 기본적으로 포함되므로, 기본 `cosign sign` 기능은 오프라인 검증에 필요한 모든 자료를 포함합니다.

에어갭 환경에서 이미지를 검증하려면, 이미지와 서명이 파일 시스템에 로컬로 존재해야 합니다.

이미지는 `cosign save`를 사용하여 로컬에 저장할 수 있습니다 (참고: 이 단계는 네트워크 연결이 있는 상태에서 수행해야 합니다):

```
cosign initialize # This will pull in the latest TUF root
cosign save $IMAGE_NAME --dir ./path/to/dir
```

이제, 에어갭 환경에서 이 로컬 이미지를 검증할 수 있습니다:

```shell
cosign verify \
  --certificate-identity $CERT_IDENTITY \
  --certificate-oidc-issuer $CERT_OIDC_ISSUER \
  --offline=true \
  --new-bundle-format=false \ # for artifacts signed without the new protobuf bundle format
  --trusted-root ~/.sigstore/root/tuf-repo-cdn.sigstore.dev/targets/trusted_root.json \ # default location of trusted root
  --local-image ./path/to/dir
```

`$CERT_IDENTITY`와 `$CERT_OIDC_ISSUER`에 대한 예상 값을 전달해야 이 이미지를 올바르게 검증할 수 있습니다.
키페어로 서명한 경우, 공개 키 자료가 로컬에 존재한다면 동일한 명령이 작동합니다:

```
cosign verify --key cosign.pub --offline --local-image ./path/to/dir
```

### ID 기반 블롭 서명 및 검증

키리스 블롭 서명(`--key` 없이 `cosign sign-blob`)을 사용하고 예상 서명자 ID에 대해 검증하세요:

```shell
$ cosign sign-blob artifact --bundle artifact.sigstore.json --yes
$ cosign verify-blob artifact \
  --bundle artifact.sigstore.json \
  --certificate-identity "https://github.com/ORG/REPO/.github/workflows/release.yml@refs/heads/main" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com"
```

### 문제 해결

Cosign 사용 중 문제가 발생하면 먼저 최신 릴리스를 사용하고 있는지 확인하세요. Cosign 프로젝트는 최신 릴리스와 v2 시리즈의 마지막 릴리스를 적극적으로 지원합니다.

#### 일반적인 문제와 해결 방법

1. `failed to verify timestamps: threshold not met for verified log entry integrated timestamps: 0 < 1` 오류와 함께 검증이 실패하는 경우: RFC3161 타임스탬프 지원이 필요한 서명을 검증하고 있을 수 있습니다
   * 최신 Cosign으로 업그레이드하거나
   * Cosign 2.6.x에서 `--use-signed-timestamps`를 사용하세요
1. `no signatures found` 오류와 함께 검증이 실패하는 경우: Rekor v2 투명성 로그 지원이 필요한 이미지 서명을 검증하고 있을 수 있습니다
   * 최신 Cosign으로 업그레이드하세요
1. HTTP 오류와 함께 서명이 실패하는 경우: Cosign을 사용한 서명은 여러 Sigstore 서비스에 의존합니다. 이러한 서비스 중 하나라도 실패하면 재시도하는 것이 유용한 해결 방법이 될 수 있습니다 -- 특정 실패에 대한 이슈를 제출해 주시면 감사하겠습니다

#### 다른 문제가 있는 경우

[이슈](https://github.com/sigstore/cosign/issues/new/choose)를 열거나 [slack 채널](#info)에서 질문해 주세요.

## 다른 아티팩트 작업

OCI 레지스트리는 컨테이너 이미지뿐만 아니라 더 많은 것을 저장하는 데 유용합니다!
`Cosign`은 또한 OCI 프로토콜을 사용하여 바이너리, 스크립트, 구성 파일을 포함한 일반 아티팩트를 게시하기 위한 몇 가지 유틸리티를 포함하고 있습니다.

이 섹션에서는 나머지 Sigstore와 잘 통합되는 사용하기 쉽고 하위 호환성이 있는 아티팩트 배포 시스템을 위해 이러한 유틸리티를 활용하는 방법을 보여줍니다.

자세한 내용은 [문서](https://docs.sigstore.dev/cosign/signing/other_types/)를 참조하세요.

### Blob

`cosign upload blob`을 사용하여 아티팩트를 게시할 수 있습니다:

```shell
$ echo "my first artifact" > artifact
$ BLOB_SUM=$(shasum -a 256 artifact | cut -d' ' -f 1) && echo "$BLOB_SUM"
c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626
$ BLOB_NAME=my-artifact-$(uuidgen | head -c 8 | tr 'A-Z' 'a-z')
$ BLOB_URI=ttl.sh/$BLOB_NAME:1h

$ BLOB_URI_DIGEST=$(cosign upload blob -f artifact $BLOB_URI) && echo "$BLOB_URI_DIGEST"
Uploading file from [artifact] to [ttl.sh/my-artifact-f42c22e0:5m] with media type [text/plain]
File [artifact] is available directly at [ttl.sh/v2/my-artifact-f42c22e0/blobs/sha256:c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626]
Uploaded image to:
ttl.sh/my-artifact-f42c22e0@sha256:790d47850411e902aabebc3a684eeb78fcae853d4dd6e1cc554d70db7f05f99f
```

사용자는 curl이나 wget 같은 표준 도구를 사용하여 "direct" URL에서 다운로드할 수 있습니다:

```shell
$ curl -L ttl.sh/v2/$BLOB_NAME/blobs/sha256:$BLOB_SUM > artifact-fetched
```

다이제스트는 URL에 바로 포함되어 있으므로, 그것도 확인할 수 있습니다:

```shell
$ cat artifact-fetched | shasum -a 256
c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626  -
```

일반적인 `cosign sign` 명령과 플래그로 서명할 수 있습니다:

```shell
$ cosign sign --key cosign.key $BLOB_URI_DIGEST
Enter password for private key:
Pushing signature to: ttl.sh/my-artifact-f42c22e0
```

평소와 같이, 서명하는 모든 이미지를 다이제스트로 참조하여 잘못된 것을 서명하지 않도록 하세요!

#### Tekton 번들

[Tekton](https://tekton.dev) 번들은 OCI 레지스트리 내에서 업로드하고 관리할 수 있습니다.
명세는 [여기](https://tekton.dev/docs/pipelines/tekton-bundle-contracts/)에 있습니다.
이는 `cosign`으로 서명하고 검증할 수도 있다는 것을 의미합니다.

Tekton 번들은 현재 [tkn cli](https://github.com/tektoncd/cli)로 업로드할 수 있지만, 향후 `cosign`에 이 지원을 추가할 수도 있습니다.

```shell
$ tkn bundle push us.gcr.io/dlorenc-vmtest2/pipeline:latest -f task-output-image.yaml
Creating Tekton Bundle:
        - Added TaskRun:  to image

Pushed Tekton Bundle to us.gcr.io/dlorenc-vmtest2/pipeline@sha256:124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155
$ cosign sign --key cosign.key us.gcr.io/dlorenc-vmtest2/pipeline@sha256:124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155
Enter password for private key:
tlog entry created with index: 5086
Pushing signature to: us.gcr.io/dlorenc-vmtest2/demo:sha256-124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155.sig
```

#### WASM

Web Assembly 모듈은 이 [사양](https://github.com/solo-io/wasm/tree/master/spec)을 사용하여 OCI 레지스트리에 저장할 수도 있습니다.

Cosign은 `cosign wasm upload` 명령을 사용하여 이를 업로드할 수 있습니다:

```shell
$ cosign upload wasm -f hello.wasm us.gcr.io/dlorenc-vmtest2/wasm
$ cosign sign --key cosign.key us.gcr.io/dlorenc-vmtest2/wasm@sha256:9e7a511fb3130ee4641baf1adc0400bed674d4afc3f1b81bb581c3c8f613f812
Enter password for private key:
tlog entry created with index: 5198
Pushing signature to: us.gcr.io/dlorenc-vmtest2/wasm:sha256-9e7a511fb3130ee4641baf1adc0400bed674d4afc3f1b81bb581c3c8f613f812.sig
```
#### eBPF

[eBPF](https://ebpf.io) 모듈은 이 [명세](https://github.com/solo-io/bumblebee/tree/main/spec)를 사용하여 OCI 레지스트리에 저장할 수도 있습니다.

아래 이미지는 `bee` 도구를 사용하여 빌드되었습니다. 더 많은 정보는 [여기](https://github.com/solo-io/bumblebee/)에서 확인할 수 있습니다.

Cosign은 다른 OCI 이미지와 마찬가지로 이러한 이미지에도 서명할 수 있습니다.

```shell
$ bee build ./examples/tcpconnect/tcpconnect.c localhost:5000/tcpconnect:test
$ bee push localhost:5000/tcpconnect:test
$ cosign sign  --key cosign.key localhost:5000/tcpconnect@sha256:7a91c50d922925f152fec96ed1d84b7bc6b2079c169d68826f6cf307f22d40e6
Enter password for private key:
Pushing signature to: localhost:5000/tcpconnect
$ cosign verify --key cosign.pub localhost:5000/tcpconnect:test

Verification for localhost:5000/tcpconnect:test --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The signatures were verified against the specified public key

[{"critical":{"identity":{"docker-reference":"localhost:5000/tcpconnect"},"image":{"docker-manifest-digest":"sha256:7a91c50d922925f152fec96ed1d84b7bc6b2079c169d68826f6cf307f22d40e6"},"type":"cosign container image signature"},"optional":null}]

```

#### In-Toto 증명

Cosign은 [in-toto](https://in-toto.io) 증명도 기본적으로 지원합니다.
이에 대한 명세는 [여기](https://github.com/in-toto/attestation)에 정의되어 있습니다.

다음 명령어를 사용하여 로컬 predicate 파일로부터 증명을 생성하고 서명할 수 있습니다:

```shell
$ cosign attest --predicate <file> --key cosign.key $IMAGE_URI_DIGEST
```

모든 표준 키 관리 시스템이 지원됩니다.
페이로드는 [여기](https://github.com/secure-systems-lab/dsse)에 정의된 DSSE 서명 사양을 사용하여 서명됩니다.

검증하려면:

```shell
$ cosign verify-attestation --key cosign.pub $IMAGE_URI
```

## 상세 사용법

더 많은 정보는 [사용법 문서](https://docs.sigstore.dev/cosign/signing/overview/)를 참조하세요.

## 하드웨어 기반 토큰

하드웨어와 함께 `cosign`을 사용하는 방법에 대한 정보는 [하드웨어 토큰 문서](https://docs.sigstore.dev/cosign/key_management/hardware-based-tokens/)를 참조하세요.

## 레지스트리 지원

`cosign`은 레지스트리 상호작용을 위해 [go-containerregistry](https://github.com/google/go-containerregistry)를 사용하며, 이는 일반적으로 뛰어난 호환성을 가지고 있지만 일부 레지스트리는 특이한 동작을 할 수 있습니다.

현재 `cosign`은 다음 레지스트리에 대해 테스트되었으며 작동합니다:

* AWS Elastic Container Registry
* GCP의 Artifact Registry 및 Container Registry
* Docker Hub
* Azure Container Registry
* JFrog Artifactory Container Registry
* The CNCF distribution/distribution Registry
* GitLab Container Registry
* GitHub Container Registry
* The CNCF Harbor Registry
* Digital Ocean Container Registry
* Sonatype Nexus Container Registry
* Alibaba Cloud Container Registry
* Red Hat Quay Container Registry 3.6+ / Red Hat quay.io
* Elastic Container Registry
* IBM Cloud Container Registry
* Cloudsmith Container Registry
* The CNCF zot Registry
* OVHcloud Managed Private Registry

우리는 폭넓은 레지스트리 지원을 목표로 합니다. 아직 [OCI 미디어 타입](https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md)을 완전히 지원하지 않는 레지스트리의 이미지에 `sign`을 수행하려면, 레거시 등가물로 폴백하기 위해 `COSIGN_DOCKER_MEDIA_TYPES`를 사용해야 할 수 있습니다. 예를 들어:

```shell
COSIGN_DOCKER_MEDIA_TYPES=1 cosign sign --key cosign.key legacy-registry.example.com/my/image@$DIGEST
```

테스트를 도와주시고 문제가 보이면 버그를 신고해 주세요!
지침은 [트래킹 이슈](https://github.com/sigstore/cosign/issues/40)에서 확인할 수 있습니다.

## 주의사항

### 의도적으로 누락된 기능

`cosign`은 임시 키리스 서명과 관리형 키 서명 모두에 대해 ECDSA-P256 키만 생성하고 SHA256 해시만 사용합니다.
키는 PEM 인코딩된 PKCS8 형식으로 저장됩니다.
그러나 `cosign`을 사용하면 모든 알고리즘의 모든 형식으로 서명을 저장하고 검색할 수 있습니다.

### 아마도 변경되어야 할 사항들

#### 페이로드 형식

`cosign`은 페이로드에 대해 Red Hat의 [simple signing](https://www.redhat.com/en/blog/container-image-signing)
형식만 지원합니다.
그 형식은 다음과 같습니다:

```json
{
    "critical": {
           "identity": {
               "docker-reference": "testing/manifest"
           },
           "image": {
               "Docker-manifest-digest": "sha256:20be...fe55"
           },
           "type": "cosign container image signature"
    },
    "optional": {
           "creator": "Bob the Builder",
           "timestamp": 1458239713
    }
}
```

**참고:** 이는 `cosign generate $IMAGE_URI_DIGEST`를 사용하여 이미지 참조에 대해 생성될 수 있습니다.

이 형식을 다른 것으로 바꾸는 것이 합리적이라면 기꺼이 변경하겠습니다.
한 가지 옵션은 https://github.com/notaryproject/notation/issues/40 을 참조하세요.

#### 레지스트리 세부 사항

`cosign` 서명은 OCI 레지스트리에 별도의 객체로 저장되며, "서명"하는 객체에 대한 참조는 약한 수준에 불과합니다.
이는 이 관계가 레지스트리에 불투명하다는 것을 의미하며, 이미지가 삭제될 때 서명은 삭제되거나 가비지 컬렉션되지 *않습니다*.
마찬가지로, 한 환경에서 다른 환경으로 쉽게 복사**될 수 있지만**, 이는 자동으로 이루어지지 않습니다.

여러 서명이 목록에 저장되는데, 안타깝게도 현재로서는 경쟁 조건(race condition)이 발생합니다.
서명을 추가하기 위해 클라이언트는 "읽기-추가-쓰기" 작업을 조정하므로, 경합이 발생할 경우 마지막 쓰기가 우선합니다.

##### 레지스트리 지정

`cosign`은 기본적으로 서명하는 이미지와 동일한 저장소에 서명을 저장합니다.
서명을 위한 다른 저장소를 지정하려면 `COSIGN_REPOSITORY` 환경 변수를 설정할 수 있습니다.

이는 제공된 이미지의 저장소를 다음과 같이 대체합니다:

```shell
$ export COSIGN_REPOSITORY=gcr.io/my-new-repo
$ cosign sign --key cosign.key $IMAGE_URI_DIGEST
```

`gcr.io/dlorenc-vmtest2/demo`의 서명은 `gcr.io/my-new-repo/demo:sha256-DIGEST.sig`에 저장됩니다.

참고: 레지스트리에 따라 "repository"에 대해 다른 형식을 기대할 수 있습니다.

* [GCR](https://cloud.google.com/container-registry)을 사용하려면 위 예시에서처럼 `gcr.io/$REPO`와 같은 레지스트리 이름이면 충분합니다.
* [Artifact Registry](https://cloud.google.com/artifact-registry)를 사용하려면 저장소만이 아니라 `$LOCATION-docker.pkg.dev/$PROJECT/$REPO/$STORAGE_IMAGE`와 같은 전체 이미지 이름을 지정하세요. 예를 들어,

  ```shell
  $ export COSIGN_REPOSITORY=us-docker.pkg.dev/my-new-repo/demo
  $ cosign sign --key cosign.key $IMAGE_URI_DIGEST
  ```

  여기서 `sha256-DIGEST`는 `gcr.io/dlorenc-vmtest2/demo`의 다이제스트와 일치합니다. `$LOCATION-docker.pkg.dev/$PROJECT/$REPO`와 같이 저장소만 지정하는 것은 Artifact Registry에서 작동하지 않습니다.


## 서명 명세

`cosign`은 [minisign](https://jedisct1.github.io/minisign/) 및 [signify](https://www.openbsd.org/papers/bsdcan-signify.html)와 같은 도구에서 영감을 받았습니다.

생성된 개인 키는 PEM 형식으로 저장됩니다.
키는 scrypt를 KDF로, nacl/secretbox를 암호화에 사용하여 비밀번호로 암호화됩니다.

PEM 헤더는 `ENCRYPTED SIGSTORE PRIVATE KEY`입니다:

```shell
-----BEGIN ENCRYPTED SIGSTORE PRIVATE KEY-----
...
-----END ENCRYPTED SIGSTORE PRIVATE KEY-----
```

공개 키는 `PUBLIC KEY` 헤더가 있는 PEM 인코딩 표준 PKIX 형식으로 디스크에 저장됩니다.
```
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELigCnlLNKgOglRTx1D7JhI7eRw99
QolE9Jo4QUxnbMy5nUuBL+UZF9qqfm/Dg1BNeHRThHzWh2ki9vAEgWEDOw==
-----END PUBLIC KEY-----
```

## 스토리지 명세

`cosign`은 서명을 OCI 레지스트리에 저장하며, 서명 인덱스를 찾기 위해 명명 규칙(서명 대상의 sha256을 기반으로 한 태그)을 사용합니다.

<p align="center">
  <img src="https://raw.githubusercontent.com/sigstore/cosign/HEAD/images/signatures.dot.svg" />
</p>

`reg.example.com/ubuntu@sha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715`의 서명은 `reg.example.com/ubuntu:sha256-703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715.sig`에 위치합니다.

대략적으로(호스트 이름의 포트를 무시하고): 서명 인덱스를 찾기 위해 `s/:/-/g`와 `s/@/:/g`를 사용합니다.

이 전략과 관련된 몇 가지 주의사항은 [경쟁 조건](#registry-details)을 참조하세요.

대안 구현으로는 투명성 로그, 로컬 파일 시스템, 별도의 리포지토리 레지스트리, 서명 인덱스에 대한 명시적 참조, 새로운 레지스트리 API, grafeas 등을 사용할 수 있습니다.

### 서명 대상

`cosign`은 현재 레지스트리에 "매니페스트"로 저장된 아티팩트에만 작동합니다.
제안된 메커니즘은 임의의 대상을 서명하는 것을 지원할 만큼 충분히 유연합니다.

### KMS 지원

`cosign`은 KMS 제공자를 사용하여 키를 생성하고 서명하는 것을 지원합니다.
현재 cosign은 Hashicorp Vault, AWS KMS, GCP KMS, Azure Key Vault를 지원하며, 앞으로 더 많은 것을 지원할 수 있기를 기대합니다!

추가 KMS 제공자는 [OVHcloud KMS](https://github.com/ovh/sigstore-kms-ovhcloud)와 같은 외부 플러그인으로 사용할 수 있습니다.

자세한 내용은 [KMS 문서](https://docs.sigstore.dev/cosign/key_management/overview/)를 참조하세요.

### OCI 아티팩트

[oras](https://github.com/deislabs/oras)를 사용하여 아티팩트를 레지스트리에 푸시합니다(이 경우 `cosign` 자체입니다!):

```shell
$ oras push us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact ./cosign
Uploading f53604826795 cosign
Pushed us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact
Digest: sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef
```

이제 서명하세요! 물론 `cosign`을 사용해서요:

```shell
$ cosign sign --key cosign.key us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact@sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef
Enter password for private key:
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact:sha256-551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef.sig
```

마지막으로, `cosign`을 다시 `cosign`으로 검증합니다:

```shell
$ cosign verify --key cosign.pub  us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact@sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The claims were present in the transparency log
  - The signatures were integrated into the transparency log when the certificate was valid
  - The signatures were verified against the specified public key
  - The code-signing certificate was verified using trusted certificate authority certificates

{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef"},"Type":"cosign container image signature"},"Optional":null}
```

## FAQ

### Notary v2를 사용하지 않는 이유

간단히 답하기 어렵습니다.
이 글에 몇 가지 비교가 포함되어 있습니다:

[Notary V2 and Cosign](https://medium.com/@dlorenc/notary-v2-and-cosign-b816658f044d)

다른 비교 글을 찾으시면 여기에 PR을 보내주시면 모두 링크하겠습니다.

### containers/image 서명을 사용하지 않는 이유

`containers/image` 서명은 `cosign`과 유사하며, 페이로드 형식을 재사용합니다.
`cosign`은 PGP 대신 ECDSA-P256 키로 서명하고, 서명을 레지스트리에 저장한다는 점에서 다릅니다.

### TUF를 사용하지 않는 이유

이 도구는 TUF와 상호 보완적이며 함께 사용할 수 있다고 생각합니다.
아직 시도해보지는 않았지만, TUF 저장소로 레지스트리를 재사용할 수도 있다고 봅니다.

## 설계 요구사항

* 서명 저장, 조회 또는 검색을 위한 외부 서비스 없음
* 가능한 한 많은 레지스트리 지원을 목표로 함
* 모든 것이 레지스트리 API를 통해 작동해야 함
* PGP는 전혀 필요하지 않아야 함.
* 사용자는 이미지에 대한 모든 서명을 찾을 수 있어야 함
* 서명자는 푸시 후 이미지에 서명할 수 있음
* 여러 주체가 이미지에 서명할 수 있음
* 이미지에 서명해도 이미지가 변경되지 않음
* 순수 Go 구현

## 향후 아이디어

### 레지스트리 API 변경

레지스트리에 무언가를 저장하기 위해 사용하는 명명 규칙과 read-modify-write 업데이트 패턴은 다소, 음, "해키"합니다.
오늘날 사용 가능한 최선의 (유일한) 실제 옵션이라고 생각하지만, 레지스트리 API가 변경되면 이를 개선할 수 있습니다.

### 기타 유형

`cosign`은 레지스트리에 있는 모든 것에 서명할 수 있습니다.
이 예제들은 단일 이미지에 서명하는 것을 보여주지만, 멀티 플랫폼 `Index`나 다른 유형의 아티팩트에도 서명할 수 있습니다.
여기에는 Helm Charts, Tekton Pipelines, 그리고 현재 배포를 위해 OCI 레지스트리를 사용하는 다른 모든 것이 포함됩니다.

이는 또한 새로운 아티팩트 유형을 레지스트리에 업로드하고 서명할 수 있다는 것을 의미합니다.
저장하고 서명할 흥미로운 유형 중 하나는 TUF 저장소입니다.
아직 시도해보지는 않았지만, TUF가 이 위에 구현될 수 있다고 상당히 확신합니다.

### 태그 서명

`cosign` 서명은 레지스트리에 저장된 객체의 다이제스트를 보호합니다.
선택적 `annotations` 지원(`cosign sign`의 `-a` 플래그를 통해)은 서명되고 서명으로 보호되는 페이로드에 추가 데이터를 더하는 데 사용할 수 있습니다.
이에 대한 한 가지 사용 사례는 tag->digest 매핑에 서명하는 것일 수 있습니다.

특정 태그(또는 태그 집합)가 다이제스트를 가리켜야 한다고 증명하려면, 다음과 같이 실행할 수 있습니다:

```shell
$ docker push $IMAGE_URI
The push refers to repository [dlorenc/demo]
994393dc58e7: Pushed
5m: digest: sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870 size: 528
$ TAG=sign-me
$ cosign sign --key cosign.key -a tag=$TAG $IMAGE_URI_DIGEST
Enter password for private key:
Pushing signature to: dlorenc/demo:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870.sig
```

그런 다음 `cosign verify`에 `-a` 플래그를 사용하여 tag->digest 매핑도 서명에 포함되어 있는지 확인할 수 있습니다.
이 예제는 `$TAG`가 가리키는 다이제스트(`sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870`)가
서명되었음을 검증하며, **또한** `tag` 어노테이션이 `sign-me` 값을 가지고 있는지도 검증합니다:

```shell
$ cosign verify --key cosign.pub -a tag=$TAG $IMAGE_URI | jq .
{
  "Critical": {
    "Identity": {
      "docker-reference": ""
    },
    "Image": {
      "Docker-manifest-digest": "97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"
    },
    "Type": "cosign container image signature"
  },
  "Optional": {
    "tag": "sign-me"
  }
}
```

타임스탬프를 여기에 추가하여 TUF 스타일의 동결 공격(freeze-attack) 방지를 구현할 수도 있습니다.

### 베이스 이미지/레이어 서명

---

[Read more](https://github.com/sigstore/cosign)
도구 다운로드