4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事は デジタル創作サークル UniProject Advent Calendar 2025 および docker Advent Calendar 2025 の 7 日目の記事です。

さて、Docker Image では、署名することで誰が Image を作ったかを検証することができるらしいですね。
以前より、Harbor(というローカルのコンテナレジストリ)でその機能を見かけてはいたものの、実際にどうするかがわかっていませんでした。

今回は、GitHub Actions で Docker Image に署名する方法を解説します。

GitHub Actions で Docker Image をビルドし、プッシュする方法については、下記記事を参考にしてください。
下記記事のワークフローを前提として記述します。
https://qiita.com/yuito_it_/items/12c2befa53beb4075011

署名とは

Docker Image への署名とは、デジタル署名をイメージに追加することで、コンテナイメージが正式な製作者によって作成されたものであることを検証することができます。

下記は Harbor での表示例ですが、確かにチェックマークがついており、しっかりと署名がなされていることが確認できます。

スクリーンショット 2025-12-28 21.15.57.png

署名の方法

署名の方法にはいくつかあるらしいのですが、今回は Cosign を使いました。
キーペアを作成することによって、公開鍵暗号を用いて署名することもできるらしいのですが、そんなめんどくさいことはしたくありません。

npm と同じく OIDC での keyless 署名が可能なようなので、今回はこちらを使用してみます。

GitHub Actions に組み込む

先の記事の通り、ビルドとプッシュができる状態にセットアップされていることを前提としています。
それが済んでいない場合は、こちらの記事をご覧ください。

さて、変更点としては 2 つです。

  1. ワークフローの権限の調整
  2. cosign のインストールと実行

1. ワークフローの権限の調整

今回は GitHub の OIDC を用いて keyless 認証を行います。
そのため、id-token:write の権限が必要となります。

permissions:
  contents: read
+ id-token: write

2. cosign のインストールと実行

cosign のインストール、そして QEMU のセットアップが必要らしいです。
(なぜ QEMU が必要なのかはいまいちよくわかっていないので詳しい人教えてください...)

最後のステップでは、metadata からのタグなどを用いて、実際に署名を行なっています。

    - name: Add metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: registry.uniproject.jp/infra/unibot
        tags: |
          type=raw,value=latest
          type=semver,pattern={{version}}
          type=semver,pattern={{major}}.{{minor}}
          type=semver,pattern={{major}}
          type=sha,prefix=,suffix=,format=short

+   - name: Install Cosign
+     uses: sigstore/cosign-installer@v3
+
+   - name: Set up QEMU
+     uses: docker/setup-qemu-action@v2
+
    - name: Build and Push Docker image
      id: build-and-push
      uses: docker/build-push-action@v5
      with:
        file: ./Dockerfile
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=registry,ref=registry.uniproject.jp/infra/unibot:buildcache
        cache-to: type=registry,ref=registry.uniproject.jp/infra/unibot:buildcache,mode=max

+   - name: Sign Docker images with GitHub OIDC (cosign keyless)
+     env:
+       TAGS: ${{ steps.meta.outputs.tags }}
+       DIGEST: ${{ steps.build-and-push.outputs.digest }}
+       COSIGN_EXPERIMENTAL: "true"
+     run: |
+       images=""
+       for tag in ${TAGS}; do
+         images="${images}${tag}@${DIGEST} "
+       done
+
+       cosign sign --yes ${images}

検証してみる

ローカルで検証してみましょう。

下記コマンドを叩くと、Overview にイメージ名などの情報が現れます。
その中の provenance に、GitHub のリポの URL が記載されていますね。

また、Attestations の中には、SLSA の詳細が記載されています。

このように表示されれば完璧です。

docker scout attest list  registry.uniproject.jp/infra/unique-api:1.0.0-alpha.3
output
    i New version 1.19.0 available (installed version is 1.18.3) at https://github.com/docker/scout-cli
    ✓ Image stored for indexing
    ✓ Indexed 20 packages
    ✓ Provenance obtained from attestation


## Overview

               │                     Analyzed Image
───────────────┼──────────────────────────────────────────────────────────
  Subject      │  registry.uniproject.jp/infra/unique-api:1.0.0-alpha.3
    digest     │  718a99479aff
    platform   │ linux/amd64
    provenance │ https://github.com/UniPro-tech/UniQUE-API
               │  72c847747ba44deaaec3ec7590c27441c94ef418
    size       │ 7.7 MB
    packages   │ 20


## Attestations

https://slsa.dev/provenance/v0.2  SLSA provenance
  Name       │  sha256:f9c0e9e98926cf36cc9af085388dc21ecb61de8d30527917f87e26e083c53c54
             │
  Media type │ application/vnd.oci.image.manifest.v1+json

Kubernetes では

署名されたイメージしか実行させないようにする AdmissionWebhook を使うのが現実的かなぁと思います。
Kyverno くらいしか思いつきませんが、これからもう少し詳しく調べてみようと思います。

最後に

今回は、Docker のイメージに署名する方法を解説しました。
よければいいね+ストックなどなどいただけるとうれしいです!

また、当サークルでは ProxmoxVE や Kubernetes を運用しています。
もし興味がありましたら、下記 URL へ飛んでいただければと思います!

⭐︎ 公式 HP ↓

⭐︎ Discord ↓

参考文献

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?