你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本文是一系列关于确保容器映像和其他开放容器计划(OCI)项目的完整性和真实性的一部分。 对于完整情况,请从概述开始,该 概述解释了签名为何重要并概述了各种方案。
本文介绍如何创建 GitHub Actions 工作流以执行以下作:
- 生成映像并将其推送到 Azure 容器注册表。
- 使用 Notation GitHub 操作和受信任签名对映像进行签名。
- 在容器注册表中自动存储生成的签名。
先决条件
设置 受信任的签名帐户和证书配置文件。 受信任的签名证书配置文件必须在其主题中包含以下属性:
- 国家/地区(
C) - 州或省(
ST或S) - 组织(
O)
公证项目规范需要这些字段。
- 国家/地区(
创建或使用 容器注册表。
创建或使用 GitHub 存储库来存储工作流文件和 GitHub 机密。
注释
目前,受信任的签名仅适用于在美国和加拿大拥有三年或以上可验证历史记录的组织。
从 Azure 到 GitHub 进行身份验证
根据 使用 GitHub Actions 连接到 Azure,在运行 Azure CLI 或 Azure PowerShell 命令之前,必须在工作流中使用 Azure 登录操作进行 Azure 身份验证。 Azure 登录作支持多种身份验证方法。
在本指南中,您将使用 OpenID Connect (OIDC) 进行登录,采用用户分配的托管标识,并遵循 使用 OpenID Connect 的 Azure 登录操作中的步骤。
创建用户分配的托管标识。 如果你有现有的托管标识,请跳过此步骤。
az login az identity create -g <identity-resource-group> -n <identity-name>
获取托管标识的客户端 ID:
CLIENT_ID=$(az identity show -g <identity-resource-group> -n <identity-name> --query clientId -o tsv)
将角色分配给用于访问 Azure 容器注册表的托管标识。
对于未启用基于属性的访问控制(ABAC)的注册表,请分配
AcrPush和AcrPull角色。ACR_SCOPE=/subscriptions/<subscription-id>/resourceGroups/<acr-resource-group> az role assignment create --assignee $CLIENT_ID --scope $ACR_SCOPE --role "acrpush" --role "acrpull"对于已启用 ABAC 的注册表,请分配
Container Registry Repository Reader和Container Registry Repository Writer角色:ACR_SCOPE=/subscriptions/<subscription-id>/resourceGroups/<acr-resource-group> az role assignment create --assignee $CLIENT_ID --scope $ACR_SCOPE --role "Container Registry Repository Reader" --role "Container Registry Repository Writer"
为访问受信任签名的托管标识分配
Trusted Signing Certificate Profile Signer角色:TS_SCOPE=/subscriptions/<subscription-id>/resourceGroups/<ts-account-resource-group>/providers/Microsoft.CodeSigning/codeSigningAccounts/<ts-account>/certificateProfiles/<ts-cert-profile> az role assignment create --assignee $CLIENT_ID --scope $TS_SCOPE --role "Trusted Signing Certificate Profile Signer"
配置 GitHub 以信任你的身份。 请按照 配置用户分配的托管标识以信任外部标识提供者 的步骤进行操作。
按照 为存储库创建机密 来创建 GitHub 机密。
将托管标识值映射到这些机密:
GitHub 机密 托管标识值 AZURE_CLIENT_ID客户 ID AZURE_SUBSCRIPTION_ID订阅编号 AZURE_TENANT_ID目录(租户)ID
存储 TSA 根证书
时间戳(RFC 3161)将签名的信任延长至签名证书的有效期之外。 受信任的签名使用生存期较短的证书,因此时间戳至关重要。 可前往 http://timestamp.acs.microsoft.com/ 获取时间戳颁发机构 (TSA) 的服务器 URL,如要了解建议,请参阅时间戳副署。
下载 TSA 根证书:
curl -o msft-tsa-root-certificate-authority-2020.crt "http://www.microsoft.com/pkiops/certs/microsoft%20identity%20verification%20root%20certificate%20authority%202020.crt"
- 将根证书存储在存储库中;例如,
.github/certs/msft-identity-verification-root-cert-authority-2020.crt. 你将在工作流中使用文件路径。
创建 GitHub Actions 工作流
在存储库中创建
.github/workflows目录(如果不存在)。创建新的工作流文件;例如,
.github/workflows/sign-with-trusted-signing.yml.将以下签名工作流模板复制到文件中。
展开以查看签名工作流模板。
# Build and push an image to Azure Container Registry, set up notation, and sign the image
name: notation-github-actions-sign-with-trusted-signing-template
on:
push:
env:
ACR_LOGIN_SERVER: <registry-login-server> # example: myregistry.azurecr.io
ACR_REPO_NAME: <repository-name> # example: myrepo
IMAGE_TAG: <image-tag> # example: v1
PLUGIN_NAME: azure-trustedsigning # name of Notation Trusted Signing plug-in; do not change
PLUGIN_DOWNLOAD_URL: <plugin-download-url> # example: "https://github.com/Azure/trustedsigning-notation-plugin/releases/download/v1.0.0-beta.1/notation-azure-trustedsigning_1.0.0-beta.1_linux_amd64.tar.gz"
PLUGIN_CHECKSUM: <plugin-package-checksum> # example: 538b497be0f0b4c6ced99eceb2be16f1c4b8e3d7c451357a52aeeca6751ccb44
TSA_URL: "http://timestamp.acs.microsoft.com/" # timestamping server URL
TSA_ROOT_CERT: <root-cert-file-path> # example: .github/certs/msft-identity-verification-root-cert-authority-2020.crt
TS_ACCOUNT_NAME: <trusted-signing-account-name> # Trusted Signing account name
TS_CERT_PROFILE: <trusted-signing-cert-profile-name> # Trusted Signing certificate profile name
TS_ACCOUNT_URI: <trusted-signing-account-uri> # Trusted Signing account URI; for example, "https://eus.codesigning.azure.net/"
jobs:
notation-sign:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
# packages: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: prepare
id: prepare
run: |
echo "target_artifact_reference=${{ env.ACR_LOGIN_SERVER }}/${{ env.ACR_REPO_NAME }}:${{ env.IMAGE_TAG }}" >> "$GITHUB_ENV"
# Log in to Azure with your service principal secret
# - name: Azure login
# uses: Azure/login@v1
# with:
# creds: ${{ secrets.AZURE_CREDENTIALS }}
# If you're using OIDC and federated credentials, make sure to replace the preceding step with the following:
- name: Azure login
uses: Azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
# Log in to your container registry
- name: ACR login
run: |
az acr login --name ${{ env.ACR_LOGIN_SERVER }}
# Build and push an image to the registry
# Use `Dockerfile` as an example to build an image
- name: Build and push
id: push
uses: docker/build-push-action@v4
with:
push: true
tags: ${{ env.target_artifact_reference }}
build-args: |
IMAGE_TAG={{ env.IMAGE_TAG }}
# Get the manifest digest of the OCI artifact
- name: Retrieve digest
run: |
echo "target_artifact_reference=${{ env.ACR_LOGIN_SERVER }}/${{ env.ACR_REPO_NAME }}@${{ steps.push.outputs.digest }}" >> "$GITHUB_ENV"
# Set up the Notation CLI
- name: setup notation
uses: notaryproject/notation-action/setup@v1.2.2
# Sign your container images and OCI artifacts by using a private key stored in Azure Key Vault
- name: sign OCI artifacts with Trusted Signing
uses: notaryproject/notation-action/sign@v1
with:
timestamp_url: ${{ env.TSA_URL}}
timestamp_root_cert: ${{env.TSA_ROOT_CERT }}
plugin_name: ${{ env.PLUGIN_NAME }}
plugin_url: ${{ env.PLUGIN_DOWNLOAD_URL }}
plugin_checksum: ${{ env.PLUGIN_CHECKSUM }}
key_id: ${{ env.TS_CERT_PROFILE }}
target_artifact_reference: ${{ env.target_artifact_reference }}
signature_format: cose
plugin_config: |-
accountName=${{ env.TS_ACCOUNT_NAME }}
baseUrl=${{ env.TS_ACCOUNT_URI }}
certProfile=${{ env.TS_CERT_PROFILE }}
force_referrers_tag: 'false'
有关环境变量的说明:
-
PLUGIN_NAME:始终使用azure-trustedsigning。 -
PLUGIN_DOWNLOAD_URL:从 受信任签名插件发布页获取 URL。 -
PLUGIN_CHECKSUM:使用发布页上的校验和文件;例如,notation-azure-trustedsigning_<version>_checksums.txt。 -
TS_ACCOUNT_URI:使用特定于其区域的受信任签名帐户的终结点;例如,https://eus.codesigning.azure.net/.
触发 GitHub Actions 工作流
语法 on:push 会触发示例工作流。 提交更改将启动工作流。 在 GitHub 存储库名称下,选择 操作 以查看工作流日志。
成功后,工作流将生成映像,将其推送到 Azure 容器注册表,并使用受信任的签名对其进行签名。 可以查看工作流日志,确认 azure-trustedsigning 插件已安装且映像已成功签名。
此外,还可以在 Azure 门户中打开容器注册表。 进入 存储库,进入您的镜像,然后选择 引用者。 确认列出了类型为 application/vnd.cncf.notary.signature 的工件(签名)。