Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article is part of a series on ensuring the integrity and authenticity of container images and other Open Container Initiative (OCI) artifacts. For the complete picture, start with the overview, which explains why signing matters and outlines the various scenarios.
This article focuses on signing by using Notary Project tooling, Notation, and Trusted Signing:
- What you'll learn here: How to use the Notation command-line interface (CLI) to sign artifacts by using Trusted Signing.
- Where it fits: Trusted Signing is an alternative to Azure Key Vault. Although Key Vault gives organizations full control of certificate lifecycle management, Trusted Signing provides streamlined signing experience with zero-touch certificate lifecycle management and short-lived certificates.
- Why it matters: Trusted Signing simplifies the developer experience while providing strong identity assurance. It helps teams reduce operational complexity without compromising security.
Prerequisites
Before you can sign and verify container images by using Notation and Trusted Signing, you need to set up the required Azure resources and install the necessary tools. This section walks you through preparing Azure Container Registry, configuring Trusted Signing, and setting up the Azure CLI as your development environment.
Note
At this time, Trusted Signing is available only to organizations based in the United States and Canada that have a verifiable history of three years or more.
Prepare container images in Azure Container Registry
- Create or use a container registry to store container images, OCI artifacts, and signatures.
- Push or use a container image in your container registry.
Set up Trusted Signing
Set up a Trusted Signing account and certificate profile in your Azure subscription.
Your certificate profile must include country/region (C), state or province (ST or S), and organization (O) in the certificate subject. The Notary Project specification requires these fields.
Set up the Azure CLI
Install the Azure CLI, or use Azure Cloud Shell.
Install the Notation CLI and Trusted Signing plug-in
This guide runs commands on Linux AMD64 and Windows as examples.
Install Notation CLI v1.3.2:
curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v1.3.2/notation_1.3.2_linux_amd64.tar.gz # Validate the checksum EXPECTED_SHA256SUM="e1a0f060308086bf8020b2d31defb7c5348f133ca0dba6a1a7820ef3cbb6dfe5" echo "$EXPECTED_SHA256SUM notation.tar.gz" | sha256sum -c - # Continue if sha256sum matches tar xvzf notation.tar.gz cp ./notation /usr/local/binFor other platforms, see the Notation installation guide.
Install the Trusted Signing plug-in:
notation plugin install --url "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" --sha256sum 538b497be0f0b4c6ced99eceb2be16f1c4b8e3d7c451357a52aeeca6751ccb44Find the latest plug-in URL and checksum on the release page.
Verify plug-in installation:
Example output:
NAME DESCRIPTION VERSION CAPABILITIES ERROR azure-trustedsigning Sign OCI artifacts using the Trusted Signing Service 0.3.0 [SIGNATURE_GENERATOR.RAW] <nil>
Configure environment variables
Set the following environment variables for use in subsequent commands. Replace placeholders with your actual values.
You can find the required values in the Azure portal:
- For Trusted Signing account information, go to your account, and then select Overview.
- For certificate profile information, go to your account, and then select Objects > Certificate Profiles.
# Trusted Signing environment variables
TS_SUB_ID="<subscription-id>"
TS_ACCT_RG=<ts-account-resource-group>
TS_ACCT_NAME=<ts-account-name>
TS_ACCT_URL=<ts-account-url>
TS_CERT_PROFILE=<ts-cert-profile>
TS_CERT_SUBJECT=<ts-cert-subject>
TS_SIGNING_ROOT_CERT="https://www.microsoft.com/pkiops/certs/Microsoft%20Enterprise%20Identity%20Verification%20Root%20Certificate%20Authority%202020.crt"
TS_TSA_URL="http://timestamp.acs.microsoft.com/"
TS_TSA_ROOT_CERT="http://www.microsoft.com/pkiops/certs/microsoft%20identity%20verification%20root%20certificate%20authority%202020.crt"
# Azure Container Registry and image environment variables
ACR_SUB_ID="<acr-subscription-id>"
ACR_RG=<acr-resource-group>
ACR_NAME=<registry-name>
ACR_LOGIN_SERVER=$ACR_NAME.azurecr.io
REPOSITORY=<repository>
TAG=<tag>
IMAGE=$ACR_LOGIN_SERVER/${REPOSITORY}:$TAG
Sign in to Azure
Use the Azure CLI to sign in with your user identity:
Note
This guide demonstrates signing in with a user account. For other identity options, including a managed identity, see Authenticate to Azure by using the Azure CLI.
Assign permissions for Azure Container Registry and Trusted Signing
Grant your identity the necessary roles to access Container Registry:
- For registries enabled with attribute-based access control (ABAC), assign:
Container Registry Repository ReaderContainer Registry Repository Writer
- For non-ABAC registries, assign:
AcrPullAcrPush
az role assignment create --role "Container Registry Repository Reader" --assignee $USER_ID --scope "/subscriptions/$ACR_SUB_ID/resourceGroups/$ACR_RG/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME"
az role assignment create --role "Container Registry Repository Writer" --assignee $USER_ID --scope "/subscriptions/$ACR_SUB_ID/resourceGroups/$ACR_RG/providers/Microsoft.ContainerRegistry/registries/$ACR_NAME"
Assign the role Trusted Signing Certificate Profile Signer to your identity so that you can sign by using Trusted Signing:
az role assignment create --assignee $USER_ID --role "Trusted Signing Certificate Profile Signer" --scope "/subscriptions/$TS_SUB_ID/resourceGroups/$TS_ACCT_RG/providers/Microsoft.CodeSigning/codeSigningAccounts/$TS_ACCT_NAME/certificateProfiles/$TS_CERT_PROFILE"
Sign a container image
# Authenticate to Azure Container Registry
az acr login --name $ACR_NAME
# Download the timestamping root certificate
curl -o msft-tsa-root-certificate-authority-2020.crt $TS_TSA_ROOT_CERT
# Sign the image
notation sign --signature-format cose --timestamp-url $TS_TSA_URL --timestamp-root-cert "msft-tsa-root-certificate-authority-2020.crt" --id $TS_CERT_PROFILE --plugin azure-trustedsigning --plugin-config accountName=$TS_ACCT_NAME --plugin-config baseUrl=$TS_ACCT_URL --plugin-config certProfile=$TS_CERT_PROFILE $IMAGE
Key flags explained:
--signature-format cose: Uses CBOR Object Signing and Encryption (COSE) format for signatures.--timestamp-url: Uses the timestamping server that Trusted Signing supports.--plugin-config: Passes configuration to the Trusted Signing plug-in.
List signed images and signatures:
Example output:
myregistry.azurecr.io/myrepo@sha256:5d0bf1e8f5a0c74a4c22d8c0f962a7cfa06a4f9d8423b196e482df8af23b5d55
└── application/vnd.cncf.notary.signature
└── sha256:d3a4c9fbc17e27b19a0b28e7b6a33f2c0f541dbdf8d2e5e8d0d79a835e8a76f2a
Verify a container image
Download and add root certificates:
curl -o msft-root-certificate-authority-2020.crt $TS_SIGNING_ROOT_CERT SIGNING_TRUST_STORE="myRootCerts" notation cert add --type ca --store $SIGNING_TRUST_STORE msft-root-certificate-authority-2020.crt curl -o msft-tsa-root-certificate-authority-2020.crt $TS_TSA_ROOT_CERT TSA_TRUST_STORE="myTsaRootCerts" notation cert add -t tsa -s $TSA_TRUST_STORE msft-tsa-root-certificate-authority-2020.crt notation cert ls
Create a trust policy JSON file:
cat <<EOF > trustpolicy.json { "version": "1.0", "trustPolicies": [ { "name": "myPolicy", "registryScopes": [ "$ACR_LOGIN_SERVER/$REPOSITORY" ], "signatureVerification": { "level" : "strict" }, "trustStores": [ "ca:$SIGNING_TRUST_STORE", "tsa:$TSA_TRUST_STORE" ], "trustedIdentities": [ "x509.subject: $TS_CERT_SUBJECT" ] } ] } EOFImport and check the policy:
notation policy import trustpolicy.json notation policy show
Verify the image:
Example output:
Successfully verified signature for myregistry.azurecr.io/myrepo@sha256:5d0bf1e8f5a0c74a4c22d8c0f962a7cfa06a4f9d8423b196e482df8af23b5d55If verification fails, ensure that your trust policy and certificates are configured correctly.
Related content
- For signing in a GitHub workflow, see Sign container images in a GitHub workflow by using Notation and Trusted Signing (preview).
- For verification in a GitHub workflow, see Verify container images in a GitHub workflow by using Notation and Trusted Signing (preview).
- For verification on Azure Kubernetes Service (AKS), see Verify container image signatures by using Ratify and Azure Policy.