【入門編】 コンテナイメージの脆弱性スキャンと署名検証(Cosign) – ガバナンス・リスク管理 & 生成AIセキュリティ防御ガイド

こんにちは!セキュリティチームのベテラン(と呼ばれつつ、日々の泥臭いログ分析に汗を流している者)です。

今回は、最近のクラウド開発現場では避けて通れない「コンテナイメージの脆弱性スキャンと署名検証(Cosign)」についてお話しします。

「コンテナ? Cosign? なんか難しそう……」と思ったそこのあなた、安心してください!
今回は、私たちが普段暮らしている「お家の防犯」に例えながら、一歩ずつ優しく紐解いていきますね。一緒にセキュリティの基礎を固めていきましょう!

—

1. コンテナのセキュリティって、お家の防犯とまったく同じなんです

みなさんは、ネット通販で買ったお皿や家具を家に届けてもらうとき、どうしていますか?
届いた段ボール箱(コンテナ)が、途中で誰かにビリビリに破られていたり、中身が怪しいものにすり替わっていたりしたら怖いですよね。

現代のシステム開発でよく使われる「Dockerコンテナ」も、これとまったく同じなんです。
インターネットの海(レジストリと呼ばれる公開倉庫)から、誰かが作った便利なプログラムの部品(コンテナイメージ)をダウンロードしてきて、自分たちのシステムという「お家」の中で動かしています。

ここで、攻撃者は何を狙うでしょうか?
彼らは、その公開倉庫にある「人気のあるお皿のセット(コンテナイメージ)」のすきを突いて、こっそり中身を「悪質なウイルス(マルウェア)」にすり替えるんです。

もし、私たちがその偽物を知らずにダウンロードしてシステムで動かしてしまったら……?
お家の合鍵を泥棒にそっくり渡してしまうようなもので、社内の大切なデータがごっそり盗まれてしまいますよね。

だからこそ、「このコンテナ、本当に安全なところから来たの?」を確認する【脆弱性スキャン】と、「これ、本物の開発者が作ったものに間違いありません!」と証明する【署名検証】の2つの防犯対策が、今のエンジニアには絶対に必要になるんです。

—

2. CI/CDパイプラインに「防犯カメラと鍵付きの門」を作ろう

「じゃあ、その防犯対策をどうやって毎日の開発に組み込めばいいの?」という話になりますよね。

手作業で毎回チェックするのは大変なので、私たちはCI/CD(GitHub Actionsなどの自動化の仕組み)という「工場の自動レーン」に、この防犯チェックを組み込んでしまいます。
コードを書いて「よし、出荷しよう!」とボタンを押した瞬間、自動で2つのチェックが走る仕組みを作るわけです。

1. 脆弱性スキャン:荷物の中に、既知の「危ないバグや穴(脆弱性)」が隠れていないか、レントゲン写真を撮ってチェックする。
2. 署名検証(Cosign):荷物の送り主が本物かどうか、特殊な「デジタル封印(署名)」をペリペリと剥がして確認する。

それでは、この自動チェックをGitHub Actionsで実際にどう書くのか、具体的な設定を見てみましょう!

—

3. 【実践】GitHub Actionsでスキャンと署名検証を自動化するコード例

百聞は一見にしかず、です。
以下の設定ファイル(YAML)は、私たちが実際の現場でよく使っているものを、初心者向けにすごくシンプルにしたものです。

name: Container Security Pipeline

# 開発者がメインブランチにコードをプッシュした時に、自動で動き出します
on:
  push:
    branches: [ "main" ]

jobs:
  build-and-secure:
    runs-on: ubuntu-latest
    
    # セキュリティ上の権限設定(GitHubの安全な場所から鍵を読み書きするため)
    permissions:
      contents: read
      id-token: write 

    steps:
      # 1. まずはお家の設計図(ソースコード)をチェックイン!
      - name: Checkout code
        uses: actions/checkout@v4

      # 2. Dockerコンテナのビルドを行います
      - name: Build the Docker image
        run: docker build -t my-app:latest .

      # 3. 【防犯チェック①】脆弱性スキャン (Trivyという有名なツールを使います)
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'my-app:latest'
          format: 'table'
          exit-code: '1' # もし致命的な脆弱性が見つかったら、ここで強制ストップ!
          severity: 'CRITICAL,HIGH' # ヤバいレベルの脆弱性だけは見逃しません

      # 4. 【防犯チェック②】Cosignを使った署名 (「これ私が安全に作りました!」とハンコを押す)
      - name: Install Cosign tool
        uses: sigstore/cosign-installer@v3

      - name: Sign the container image
        env:
          COSIGN_EXPERIMENTAL: "true"
        run: |
          # 秘密鍵を使って、ビルドしたイメージにデジタル署名(ハンコ)をペタリ
          # ※実際の運用ではキーレス署名やKMSなどの安全な鍵管理を使います
          echo "コンテナイメージにデジタル署名を付与しています..."
          # cosign sign --yes my-app:latest (※サンプル用のプレースホルダーです)

この設定のすごいところは、ステップ3(Trivy)で「危ない穴が見つかったら、自動的に出荷を止める」ようになっている点です。
人間はうっかり見落としてしまうこともありますが、ロボット(CI/CD)なら絶対に見逃しません。

—

4. 署名検証(Cosign)で「偽物の荷物」を徹底ブロック!

さて、スキャンを通り抜けたコンテナですが、最後に本番サーバーへデプロイ(配置)する前にもう一度だけ重要な関門があります。それがCosignによる署名検証です。

これは、宅配便で言えば「荷物の送り状にあるホログラムシールが本物かどうか、特殊なライトを当てて確認する作業」に似ています。

もし、途中で悪意ある第三者がコンテナをすり替えていたらどうなるでしょうか?
その偽物のコンテナには「正しいデジタル署名(ハンコ)」がついていないため、本番サーバーの門番(Kubernetesやデプロイツール)が「おい、このハンコ偽物だぞ!通すわけにはいかない!」と、自動でガチャンと門を閉めてくれます。

# 本番サーバー側で行う検証コマンドのイメージ
cosign verify \
  --certificate-identity "https://github.com/your-username/your-repo/.github/workflows/deploy.yml@refs/heads/main" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  my-app:latest

このように、Cosignを使うことで「誰が・いつ・どの安全なプロセスを経て作ったイメージなのか」を暗号学的にガチガチに証明できるんです。

—

一歩ずつ、確実なセキュリティを

いかがでしょうか?
「コンテナの脆弱性スキャン」も「Cosignでの署名検証」も、やっている本質は「お家に変なものを入れないための、現代版の戸締まりと身元確認」にすぎません。

最初は覚えることが多くてクラクラするかもしれませんが、一度こうしてCI/CDという自動の仕組みに組み込んでしまえば、あとは毎日の開発を後ろから力強く支えてくれる最高の相棒になってくれます。

完璧を目指す必要はありません。まずは小さくスキャンを導入することから、一歩ずつ進めていきましょう!
あなたの安全で快適な開発ライフを、セキュリティチームはいつも応援しています!

コメント

タイトルとURLをコピーしました