イメージおよび非イメージ成果物の署名の検証
イメージの署名を検証することにより、デプロイメント前に継続的統合 (CI) パイプラインで作成されたイメージの整合性を維持します。
開始前に
画像認証の作業を開始する前に、以下の前提条件が満たされていることを確認してください。
- GPG 公開鍵を持っている必要があります。 GPG キーの生成については、 資料 を参照してください。
- base 64 エンコード GPG 公開鍵を使用して環境変数
code-signing-certificateを追加する必要があります。 - 検証中にコンテナイメージにアクセスするには、レジストリの認証情報を設定する必要があります( 「レジストリの認証情報の設定 」を参照)。
イメージの検証
新しい prod-verify-artifact ステージは、 Continuous Delivery (CD) パイプライン内のイメージの署名を検証します。 このステージでは、以下のステップを実行します。
-
ユーザー提供のエンコードされた GPG 公開鍵を一時ファイルにデコードします。
-
公開鍵を使用して Docker コンテナー・ポリシー (
/etc/containers/policy.json) を作成します。{ "default": [ { "type": "reject" } ], "transports": { "docker-daemon": { "": [ { "type": "reject" } ] }, "docker": { "": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/tmp/GPGPublicKey" } ] } } } -
Skopeo を使用してコンテナー・ポリシーでイメージをプルすることにより、各成果物の成果物のリストを取得します。
skopeo copy docker://"${image}" dir:"${tmp_sign_dir}" --src-creds iamapikey:"${ibmcloud_api_key}"
署名が有効であり、ユーザーによって提供された公開鍵によって検証される場合、イメージ・プルは成功します。
検証用のレジストリ認証情報の設定
コンテナイメージの署名を検証する際、パイプラインではコンテナレジストリへの認証や署名済みイメージへのアクセスを行うために、認証情報が必要となります。 DevSecOps パイプラインは、実行時の動的な認証情報の解決をサポートしており、自動フォールバック機能を利用して、さまざまな方法で認証情報を設定することができます。
認証情報の解決階層
このパイプラインは、実行時に以下の階層構造に従って、ユーザー名とAPIキーの両方の認証情報を動的に解決します:
APIキーの解決順序:
- ネームスペース固有のAPIキー :
signing-token-apikey-{registry}-{namespace}(シークレット) - レジストリ固有のAPIキー :
signing-token-apikey-{registry}(シークレット) - Docker 設定JSON:
signing-dockerconfigjson(非公開) - ICR固有のフォールバック :
ciso-ibmcloud-api-key(秘密)ibmcloud-api-key(秘密)
ユーザー名の解決順序:
- 名前空間固有のユーザー名:
signing-token-username-{registry}-{namespace}(環境変数) - レジストリ固有のユーザー名 :
signing-token-username-{registry}(環境変数) - デフォルト:
iamapikey(ユーザー名が設定されていない場合)
ここで、
{registry}レジストリのホスト名です(例:us.icr.io、de.icr.io){namespace}スラッシュとドットがアンダースコアに置き換えられた完全な名前空間パスです(例:my_namespace_path)
ネームスペース固有の認証情報の設定
きめ細かなアクセス制御を行うには、レジストリの名前空間ごとに固有の認証情報を設定できます:
APIキー(シークレット) : signing-token-apikey-{registry}-{namespace}
ユーザー名(環境変数) : signing-token-username-{registry}-{namespace}
例 :画像の場合 us.icr.io/my-namespace/my-app:latest
- registry:
us.icr.io - 名前空間:
my-namespace - APIキーのシークレット:
signing-token-apikey-us.icr.io-my_namespace - ユーザー名環境変数:
signing-token-username-us.icr.io-my_namespace - ユーザー名が指定されていない場合、デフォルトは次の通りです:
iamapikey
レジストリ固有の認証情報の設定
レジストリ内のすべての名前空間に広くアクセスするには:
APIキー(シークレット) : signing-token-apikey-{registry}
ユーザー名(環境変数) : signing-token-username-{registry}
例 :内の任意の画像について us.icr.io
- APIキーのシークレット:
signing-token-apikey-us.icr.io - ユーザー名環境変数:
signing-token-username-us.icr.io - ユーザー名が指定されていない場合、デフォルトは次の通りです:
iamapikey
Docker の設定JSONファイルの設定
複数のレジストリの認証情報を含む、 base64-encoded Docker の設定JSONを指定できます:
秘密の名前 : signing-dockerconfigjson
形式 : Base64-encoded ( Docker の config.json 形式に準拠した JSON):
{
"auths": {
"us.icr.io": {
"username": "iamapikey",
"password": "your-api-key"
},
"us.icr.io/my-namespace": {
"username": "iamapikey",
"password": "namespace-specific-key"
}
}
}
パイプラインは最も具体的なパスから順に一致させるため、 Docker の設定内で名前空間レベルでの上書きが可能になります。
構成の例
画像については us.icr.io/production/my-app:v1.0.0 をご覧ください:
オプション 1: 名前空間固有(本番環境での使用を推奨)
- APIキーのシークレット:
signing-token-apikey-us.icr.io-production=your-namespace-api-key - ユーザー名環境変数(任意):
signing-token-username-us.icr.io-production=iamapikey - ユーザー名が指定されていない場合、デフォルトでは
iamapikey
オプション 2: レジストリ全体
- APIキーのシークレット:
signing-token-apikey-us.icr.io=your-registry-api-key - ユーザー名環境変数(任意):
signing-token-username-us.icr.io=iamapikey - ユーザー名が指定されていない場合、デフォルトでは
iamapikey
オプション 3: Docker の設定 JSON
- 秘密:
signing-dockerconfigjson=base64-encoded-docker-config - ユーザー名は、 Docker の設定JSONから抽出されます
オプション 4: IBM Cloud デフォルト(ICRの場合は自動)
- APIキーのシークレット:
ibmcloud-api-key=your-ibmcloud-api-key - ユーザー名はデフォルトで
iamapikey
イメージ以外の成果物の検証
DevSecOps のパイプラインでは、署名付きアーティファクトの署名が検証の対象となります。 このセクションでは、成果物の検証に進む前にユーザーが満たす必要がある前提条件について概説します。
開始前に
イメージ検証を操作する前に、以下の前提条件を満たしていることを確認してください。
-
パイプライン構成を変更して、検証プロセスを有効にします。
.pipeline-config.yamlファイルに、以下のコードスニペットを追加してください。verify-artifact: image: icr.io/continuous-delivery/pipeline/image-signing:1.0.0@sha256:e9d8e354668ba3d40be2aaee08298d2aa7f0e1c8a1829cca4094ec93830e3e6a image_pull_policy: IfNotPresent abort_on_failure: false dind: true script: | #!/usr/bin/env bash source /opt/commons/verify-artifact/verify_non_image_artifact.sh -
成果物をダウンロードして、パイプライン・ランタイムに保管します。
verify-artifactステージを呼び出す前に、必要な成果物をダウンロードして Cocoa ランタイムに保管します。 デフォルトでは、list_artifactsコレクションにリストされているすべてのアーティファクトが検証されます。skip-sign-artifact-typeテキストプロパティを使用すると、指定されたアーティファクトタイプ(例:log、report、documentation)に対して、イメージの署名検証をスキップできます。 以下のサンプルコードは、 Cloud Object Storage からアーティファクトをダウンロードし、Cocoa ランタイムに保存する方法を示しています:#!/usr/bin/env bash export SECRET_PATH="/config/ibmcloud-api-key" . "${ONE_PIPELINE_PATH}"/iam/get_token SKIP_SIGN_ARTIFACTS_TYPE="$(get_env skip-sign-artifact-type "")" IFS=';' read -ra ARTIFACT_LIST <<<"$SKIP_SIGN_ARTIFACTS_TYPE" list_artifacts | while IFS= read -r artifact; do type="$(load_artifact "$artifact" "type")" if [[ ! "${ARTIFACT_LIST[@]}" =~ "$type" ]] && [[ "$type" != "image" ]]; then inventory_entry="$(load_artifact "$artifact" "inventory-entry")" inventory_entry=${inventory_entry///artifacts/$WORKSPACE} artifact_url=$(jq -r .'app_artifacts.artifact_url' ${inventory_entry}) echo "downloading the artifact ${artifact_url}" curl -H "Authorization: bearer ${IAM_ACCESS_TOKEN}" --output outputfile ${artifact_url} save_file "${artifact}" outputfile fi done
成果物の検証
成果物検証プロセスでは、ユーザー提供の GPG 公開鍵が GPG 鍵リングにインポートされます。 list_artifacts コレクションにリストされているすべての成果物が検証されます。 このステージでは、インベントリーから署名を取得し、以下の検証を実行します。
gpg --verify "${signature}" "${artifactName}"
署名が有効であり、提供された公開鍵を使用して検証された場合、ステージは証拠を記録し、ステージに成功のマークを付けます。