AWS環境でのコンテナイメージへのユースカジノ クレジットカード
投稿日: 2023/3/30
はじめに
近年、ソフトウェアサプライチェーンの安全性の問題が注目を集めており、さまざまな組織から対策のためのガイドラインが提供されています。
その中で求められるプラクティスのひとつに、ビルド生成物(アーティファクト)に対するユースカジノ クレジットカードがあります。例えば、CIS が提供しているガイドライン「Software Supply Chain Security Guide」では、項目 4.1.1 で "Ensure all artifacts are signed by the build pipeline itself" としてビルドパイプラインによるアーティファクトへのユースカジノ クレジットカードを推奨しており、単純なユースカジノ クレジットカード検証プロセスで攻撃者によるアーティファクトの改変を検出できるであろうとしています。
また、AWSからも、「コンテナにおけるデジタルユースカジノ クレジットカード」というブログ記事で、特にコンテナイメージへのユースカジノ クレジットカードの重要性について紹介されています。
本記事では、上記ブログ記事と同じくアーティファクトとしてコンテナイメージを想定し、AWS環境のビルドパイプライン上で、ユースカジノ クレジットカード例を示します。
Cosign
ユースカジノ クレジットカード手段はいくつかありますが、本記事の例ではCosignというツールをユースカジノ クレジットカードします。
Cosign は、Sigstoreというプロジェクトの一部です。Sigstore は Linux Foundation がホストするプロジェクトで、サプライチェーンの向上のため、ソフトウェアに対するデジタルユースカジノ クレジットカードを利用しやすくするサービスを提供しています。
Cosign はユースカジノ クレジットカードレジストリとして AWS ECR を(参照)、ユースカジノ クレジットカード管理サービスとして KMS を(参照)サポートしており、AWS環境でのコンテナイメージへのユースカジノ クレジットカードと検証を比較的容易に行うことができます。
本記事では Cosign バージョン 2.0.0 をユースカジノ クレジットカードします。
構成
本記事でのシステム構成はユースカジノ クレジットカード通りです。
ユースカジノ クレジットカードパイプライン用の CodePipeline
ビルド用のパイプラインでは、以下の流れでイメージのビルドとユースカジノ クレジットカードを行います。
- 1. CodeCommit から Dockerfile を取得し、CodeBuild でユースカジノ クレジットカードをビルド
- 2. CodeBuild から ECR にユースカジノ クレジットカードをプッシュ
- 3. CodeBuild で、KMS管理のプライベートキーによりイメージにユースカジノ クレジットカード (Cosignを使用)
ユースカジノ クレジットカードパイプライン用の CodePipeline
デプロイ用のパイプラインでは、以下の流れでイメージのユースカジノ クレジットカード検証とデプロイを行います。
- 1. CodeCommit からimagedefinitions.jsonを取得し、デプロイ対象のユースカジノ クレジットカードURIを取得
- 2. CodeBuild で、KMS管理のパブリックキーによりイメージのユースカジノ クレジットカードを検証(Cosignを使用)
- 3. ユースカジノ クレジットカードに問題なければ imagedefinitions.json の内容を ECS にデプロイ
ユースカジノ クレジットカード用KMSキー
イメージへのユースカジノ クレジットカードには、ユースカジノ クレジットカード用のプライベートキーと、それを検証するためのパブリックキーのペアが必要です。
Cosignは各種クラウドのキー管理サービスと統合されており、AWS KMSの場合も、キーIDやエイリアスを指定するだけでそのキーを使用してユースカジノ クレジットカードできます。これによりプライベートキーをファイルで管理する必要がなくなり、安全性と利便性が向上します。
ユースカジノ クレジットカード用のキーであるため、KMSキーの作成時に、キーの種類「非対称」、キーの使用「ユースカジノ クレジットカードおよび検証」を選択します。今回は、以下の仕様で作成しました。
また、ユースカジノ クレジットカードにはcosign
というエイリアスを設定しています。
以降では、それぞれのパイプラインの詳細を見ていきます。
ユースカジノ クレジットカードパイプライン
ユースカジノ クレジットカードパイプラインの構成は以下のようになっています。
Sourceステージは CodeCommit からソースコードを取得しているだけですので、イメージのビルドとユースカジノ クレジットカードを行っている DockerBuild ステージの内容を見ていきます。
buildspec.yaml
DockerBuild で使用する buildspec.yaml の内容はユースカジノ クレジットカード通りです。
version: 0.2
env:
variables:
AWS_ACCOUNT_ID: "<AWSアカウントID"
IMAGE_NAME: "demo"
phases:
install:
commands:
- echo "Installing Cosign..."
- wget -nv "https://github.com/sigstore/cosign/releases/download/v2.0.0/cosign_2.0.0_amd64.deb" -O cosign_amd64.deb
# 本来はパッケージの検証が必要
- dpkg -i cosign_amd64.deb
- cosign version
pre_build:
commands:
- echo "Building image..."
- IMAGE_TAG=$(echo "$CODEBUILD_RESOLVED_SOURCE_VERSION" | head -c 7)
- docker build -t "${IMAGE_NAME}:${IMAGE_TAG}" .
- echo "Logging in to ECR..."
- IMAGE_DOMAIN="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"
- aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${IMAGE_DOMAIN}
build:
commands:
- echo "Pushing image..."
- IMAGE_FULLNAME="${IMAGE_DOMAIN}/${IMAGE_NAME}"
- docker tag "${IMAGE_NAME}:${IMAGE_TAG}" "${IMAGE_FULLNAME}:${IMAGE_TAG}"
# プッシュしたユースカジノ クレジットカードのダイジェスト値を取得
- docker push "${IMAGE_FULLNAME}:${IMAGE_TAG}" | tee -a docker-push.log
- |
IMAGE_DIGEST=$(sed -ne "s/^${IMAGE_TAG}: digest: \([^[:space:]]\+\).*/\1/ip" docker-push.log)
- test -n "${IMAGE_DIGEST}"
- echo "Signing image..."
- cosign sign --tlog-upload=false --key awskms:///alias/cosign "${IMAGE_FULLNAME}@${IMAGE_DIGEST}"
ユースカジノ クレジットカードの各フェーズの内容について説明します。
installフェーズ
installフェーズでは、公式ドキュメントに従って Cosign をインストールしています。
pre_build フェーズ
pre_build フェーズでは、ユースカジノ クレジットカードのビルドとECRへのログインを行っています。
ユースカジノ クレジットカードのタグには、CodeBuildのコミットIDを表す$CODEBUILD_RESOLVED_SOURCE_VERSION
を参照して、コミットIDの先頭を取り出して設定しています。
buildフェーズ
build フェーズでは、ビルドしたイメージをECRにプッシュし、ユースカジノ クレジットカードを行っています。
ユースカジノ クレジットカードは、プッシュしたイメージのURIを使用して、cosign signコマンドで実施しています。
cosign sign --tlog-upload=false --key awskms:///alias/cosign <ユースカジノ クレジットカード対象イメージのURI
--key
は、ユースカジノ クレジットカード用のKMSキーを指定するパラメーターです。プレフィックスawskms:///
をつけるとAWS KMSのユースカジノ クレジットカードを直接参照できます。
今回はエイリアスを設定しているため、ユースカジノ クレジットカードはawskms:///alias/<KMSユースカジノ クレジットカードのエイリアス
という形式で指定できます。 エイリアスをユースカジノ クレジットカードせずawskms:///<ユースカジノ クレジットカードID
という形式でID指定することも可能です。
ユースカジノ クレジットカードの格納先
イメージへのユースカジノ クレジットカードは、cosign sign
コマンドによって、コンテナユースカジノ クレジットカードのレジストリ(今回はECRリポジトリ)に<ユースカジノ クレジットカード対象イメージのダイジェスト.sig
のようなタグで格納されます。
例えば、下記の画像では、タグ42702b6
のユースカジノ クレジットカードのダイジェストsha256:d21ca72~
を元にして、sha256-d21ca72~.sig
というタグでユースカジノ クレジットカードが格納されている様子がわかります。
ユースカジノ クレジットカード用のタグの命名規則や、ユースカジノ クレジットカードの内容についての詳細な仕様はhttps://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.mdを参照してください。
ユースカジノ クレジットカード対象の指定
ユースカジノ クレジットカード対象のイメージは、ダイジェストを使用して厳密に指定することが推奨されています。イメージのURIをダイジェストで指定する場合、以下の例のようにリポジトリ名と@
で区切ります。
ユースカジノ クレジットカード;AWSアカウントID.dkr.ecr.ユースカジノ クレジットカード;リージョン.amazonaws.com/demo@sha256:d21ca72c272893b457c4fe47020131af88eb018a185524a5755001c70d76220f
プッシュしたユースカジノ クレジットカードのダイジェスト値を取得する簡単な方法がわからなかったため、ログをパースして取得しています。
ダイジェストではなくタグでユースカジノ クレジットカード対象を指定すると、Cosignは以下のように警告を出します。可能な限りダイジェストで指定した方が良いでしょう。
WARNING: Image reference ユースカジノ クレジットカード;AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/demo:0c4cc01 uses a tag, not a digest, to identify the image to sign.
This can lead you to sign a different image than the intended one. Please use a
digest (example.com/ubuntu@sha256:abc123...) rather than tag
(example.com/ubuntu:latest) for the input to cosign. The ability to refer to
images by tag will be removed in a future release.
Transparency Log
Cosign は、デフォルトでは Sigstore プロジェクトが提供するRekorというログサービスに Transparency Log(透明性ログ)を格納し、第三者がユースカジノ クレジットカードできるようにしています。
ただし、今回の構成はプライベートなユースカジノ クレジットカードを想定しており、ユースカジノ クレジットカードの情報を外部に公開したくありません。そのため、--tlog-upload=false
オプションを指定して Transparency Log
を Rekor にアップロードする処理を無効にしています。
今回は適用していませんが、この場合でもTSA(Timestamping Authority Service, 時刻認証局サービス)を使用して、過去の時点で正しいユースカジノ クレジットカード者にユースカジノ クレジットカードされていたことを検証可能にすることができます。詳細は以下のページを参照してください。
https://www.chainguard.dev/unchained/how-to-sign-private-artifacts-securely
ユースカジノ クレジットカードロール権限
ビルド・ユースカジノ クレジットカード用のCodeBuildのサービスロールには、デフォルトで作成される権限に加えて、以下のIAMポリシーを付与します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage"
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
],
"Resource": [
"arn:aws:ecr:<リージョン:<AWSアカウントID:repository/<リポジトリ名"
]
},
{
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:GetPublicKey",
"kms:Sign"
],
"Resource": [
"arn:aws:kms:<リージョン:<AWSアカウントID:key/<ユースカジノ クレジットカード用のキーID"
]
}
]
}
ECRに対する権限は、リポジトリにイメージとユースカジノ クレジットカードを格納するためのものです。特別な内容はありません。
KMSに対する権限の目的は、Cosignが非対称KMSキーのプライベートキーを使用してユースカジノ クレジットカードを行うことです。エイリアスの解決のためにkms:DescribeKey
、ユースカジノ クレジットカードのためにkms:Sign
と
kms:GetPublicKey
の権限が必要となっています。
さて、これでイメージとそのユースカジノ クレジットカードがECRに格納されました。次は、このイメージをデプロイするパイプラインを見ていきましょう。
ユースカジノ クレジットカードパイプライン
デプロイパイプラインの構成はユースカジノ クレジットカードようになっています。
Sourceステージは CodeCommit からソースコードを取得し、DeployステージはECSに新しいイメージを反映させているだけですので、イメージのユースカジノ クレジットカード検証を行っている Verify ステージの内容を見ていきます。
buildspec.yaml
Verifyステージの CodeBuild では、後続の Deploy ステージでECSにイメージをデプロイする前に、正当なビルドプロセスでユースカジノ クレジットカードされたイメージかどうかを検証します。
使用する buildspec.yaml の内容はユースカジノ クレジットカード通りです。
version: 0.2
env:
variables:
AWS_ACCOUNT_ID: "<AWSアカウントID"
phases:
install:
commands:
- echo "Installing Cosign..."
- wget -nv "https://github.com/sigstore/cosign/releases/download/v2.0.0/cosign_2.0.0_amd64.deb" -O cosign_amd64.deb
# 本来はパッケージの検証が必要
- dpkg -i cosign_amd64.deb
- cosign version
pre_build:
commands:
- echo "Logging in to ECR..."
- IMAGE_DOMAIN="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"
- aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${IMAGE_DOMAIN}
build:
commands:
- echo "Verifying image..."
# 今回はユースカジノ クレジットカードは1つのみの想定
- IMAGE_URI="$(jq -r .[0].imageUri imagedefinitions.json)"
- echo "IMAGE_URL=${IMAGE_URI}"
- test -n "${IMAGE_URI}"
- cosign verify --insecure-ignore-tlog --key awskms:///alias/cosign "${IMAGE_URI}"
artifacts:
files:
- imagedefinitions.json
ユースカジノ クレジットカードの各フェーズの内容について説明します。
installフェーズ
installフェーズでは、ユースカジノ クレジットカード時と同じく、Cosignをインストールします。
pre_buildフェーズ
pre_buildフェーズでは、Cosignからリポジトリに保管されているイメージユースカジノ クレジットカードを参照するために、ECRにログインしています。
buildフェーズ
buildフェーズで、実際にユースカジノ クレジットカードを検証しています。
デプロイ対象のユースカジノ クレジットカードはソースコードの imagedefinitions.json
に以下のように記載されており、この中のimageUri
からユースカジノ クレジットカードのURIを取得できます。
[{
"name": "demo",
"imageUri": "ユースカジノ クレジットカード;AWSアカウントID.dkr.ecr.ap-northeast-1.amazonaws.com/demo@sha256:d21ca72c272893b457c4fe47020131af88eb018a185524a5755001c70d76220f"
}]
取得したイメージURIを使用して、以下のコマンドでユースカジノ クレジットカードを検証しています。
cosign verify --insecure-ignore-tlog --key awskms:///alias/<非対称KMSキーのエイリアス <検証対象ユースカジノ クレジットカードのURI
ユースカジノ クレジットカード時に Transparency Log の記録をスキップしたため、--insecure-ignore-tlog
オプションを指定してユースカジノ クレジットカードもスキップしています。Rekor
にログを記録している場合は、このオプションは不要です。
ユースカジノ クレジットカードロール権限
ユースカジノ クレジットカード検証用のCodeBuildのサービスロールには、デフォルトで作成される権限に加えて、以下のIAMポリシーを付与します。
:<AWSアカウントID:key/<ユースカジノ クレジットカード用のキーID"
]
}
]
}
ECRに対する参照権限は、リポジトリに保管されているユースカジノ クレジットカードデータを参照するためのものです。
KMSに対する権限の目的は、Cosignがユースカジノ クレジットカードを検証するためにパブリックキーを取得することです。エイリアスの解決のためにkms:DescribeKey
、パブリックユースカジノ クレジットカード自体の取得のためにkms:GetPublicKey
の権限が必要となっています。
ユースカジノ クレジットカード
ユースカジノ クレジットカードの検証に失敗すると、コマンドが 0以外のコードで終了するため、Verifyステージが失敗し、後続のデプロイには進まなくなります。
これにより、イメージのユースカジノ クレジットカードが検証できた場合のみデプロイさせることができます。
まとめ
Cosignを使用することで、AWS環境のビルドパイプラインの中に、イメージに対するユースカジノ クレジットカードと検証を容易に組み込むことができました。
次回は、別のプラクティスであるSBOM (Software Bill of Materials)の生成と保存を試します。
カジノゲームは、AWSのビジネス利活用に向けて、お客様のステージに合わせた幅広い構築・運用支援サービスを提供しています。
経験豊富なエンジニアが、ワンストップかつ柔軟にご支援します。
ぜひ、お気軽にお問い合わせください。