驗證映像檔和非映像檔構件簽章
透過驗證映像檔簽章,在部署之前維護在 Continuous Integration (CI) 管線中建置之映像檔的完整性。
開始之前
在開始使用圖片驗證功能之前,請確認您已具備以下先決條件。
驗證映像檔
新的 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
- 登錄:
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}"
如果簽章有效並使用提供的公開金鑰進行驗證,則階段將記錄證明並將階段標示為成功。