1"use strict";(globalThis.webpackChunkratify=globalThis.webpackChunkratify||[]).push([[1814],{5450(e,n,i){i.d(n,{A:()=>r});const r=i.p+"assets/images/ratify-azure-e2e.drawio-f693c6aad86608bf02c61082c25c262f.svg"},28453(e,n,i){i.d(n,{R:()=>t,x:()=>o});var r=i(96540);const s={},a=r.createContext(s);function t(e){const n=r.useContext(a);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),r.createElement(a.Provider,{value:n},e.children)}},76241(e,n,i){i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"quickstarts/ratify-on-azure","title":"Ratify on Azure","description":"Signing container images ensure their authenticity and integrity. By deploying only signed images on Azure Kubernetes Service (AKS), you can ensure that the images come from a trusted origin and have not been altered since they were created.","source":"@site/versioned_docs/version-1.2/quickstarts/ratify-on-azure.md","sourceDirName":"quickstarts","slug":"/quickstarts/ratify-on-azure","permalink":"/docs/1.2/quickstarts/ratify-on-azure","draft":false,"unlisted":false,"editUrl":"https://github.com/ratify-project/ratify-web/blob/main/versioned_docs/version-1.2/quickstarts/ratify-on-azure.md","tags":[],"version":"1.2","sidebarPosition":2,"frontMatter":{"title":"Ratify on Azure","sidebar_position":2},"sidebar":"tutorialSidebar","previous":{"title":"Manual Quick Start Steps","permalink":"/docs/1.2/quickstarts/quickstart-manual"},"next":{"title":"Ratify with AWS Signer","permalink":"/docs/1.2/quickstarts/ratify-with-aws-signer"}}');var s=i(74848),a=i(28453);const t={title:"Ratify on Azure",sidebar_position:2},o="Ratify on Azure: Allow only signed images to be deployed on AKS with Ratify",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Configure environment variables",id:"configure-environment-variables",level:3},{value:"Prepare container images in ACR",id:"prepare-container-images-in-acr",level:2},{value:"Sign container images in ACR",id:"sign-container-images-in-acr",level:2},{value:"Use Notation with certificates stored in AKV",id:"use-notation-with-certificates-stored-in-akv",level:3},{value:"Use Cosign with keys stored in AKV",id:"use-cosign-with-keys-stored-in-akv",level:3},{value:"Set up an Azure workload identity",id:"set-up-an-azure-workload-identity",level:2},{value:"Create a Workload Federated Identity.",id:"create-a-workload-federated-identity",level:3},{value:"Authoring access to ACR",id:"authoring-access-to-acr",level:3},{value:"Authoring access to AKV",id:"authoring-access-to-akv",level:3},{value:"Image signed with Notation and certificates in AKV",id:"image-signed-with-notation-and-certificates-in-akv",level:4},{value:"Images signed with Cosign and keys in AKV",id:"images-signed-with-cosign-and-keys-in-akv",level:4},{value:"Set up your AKS cluster",id:"set-up-your-aks-cluster",level:2},{value:"Install Gatekeeper and Ratify in AKS",id:"install-gatekeeper-and-ratify-in-aks",level:2},{value:"When Azure Policy Addon is not enabled",id:"when-azure-policy-addon-is-not-enabled",level:3},{value:"When Azure Policy Addon is enabled on AKS",id:"when-azure-policy-addon-is-enabled-on-aks",level:3},{value:"Configure Ratify",id:"configure-ratify",level:2},{value:"Create a custom resource for accessing ACR",id:"create-a-custom-resource-for-accessing-acr",level:3},{value:"Create a custom resource for accessing AKV",id:"create-a-custom-resource-for-accessing-akv",level:3},{value:"Configure the Notation verifier resource for verifying images signed with Notation",id:"configure-the-notation-verifier-resource-for-verifying-images-signed-with-notation",level:3},{value:"Configuration for images signed with Cosign using keys in AKV",id:"configuration-for-images-signed-with-cosign-using-keys-in-akv",level:3},{value:"Deploy container images in AKS",id:"deploy-container-images-in-aks",level:2},{value:"Other scenarios",id:"other-scenarios",level:2},{value:"Fine-tuned trust policy for Cosign verifier",id:"fine-tuned-trust-policy-for-cosign-verifier",level:3},{value:"Rotate the key used by Cosign",id:"rotate-the-key-used-by-cosign",level:3},{value:"Disable the specific version of key used by Cosign",id:"disable-the-specific-version-of-key-u
1sed-by-cosign",level:3}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"ratify-on-azure-allow-only-signed-images-to-be-deployed-on-aks-with-ratify",children:"Ratify on Azure: Allow only signed images to be deployed on AKS with Ratify"})}),"\n",(0,s.jsx)(n.p,{children:"Signing container images ensure their authenticity and integrity. By deploying only signed images on Azure Kubernetes Service (AKS), you can ensure that the images come from a trusted origin and have not been altered since they were created."}),"\n",(0,s.jsxs)(n.p,{children:["With Azure Container Registry (ACR), you can store and distribute images with signatures together. You can use Azure Key Vault (AKV) to keep your signing keys and certificates safe, and then use tools like ",(0,s.jsx)(n.a,{href:"https://github.com/notaryproject/notation",children:"Notation"})," or ",(0,s.jsx)(n.a,{href:"https://github.com/sigstore/cosign",children:"Cosign"})," to sign your container images with them."]}),"\n",(0,s.jsx)(n.p,{children:"This article walks you through an end-to-end workflow of deploying only signed images on AKS with Ratify."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"e2e workflow diagram",src:i(5450).A+""})}),"\n",(0,s.jsx)(n.p,{children:"In this article:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#prepare-container-images-in-acr",children:"Prepare container images in ACR"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#sign-container-images-in-acr",children:"Sign container images in ACR"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#use-notation-with-certificates-stored-in-akv",children:"Use Notation with certificates stored in AKV"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#use-cosign-with-keys-stored-in-akv",children:"Use Cosign with keys stored in AKV"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#set-up-an-azure-workload-identity",children:"Set up an Azure workload identity"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#set-up-your-aks-cluster",children:"Set up your AKS cluster"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#install-gatekeeper-and-ratify-in-aks",children:"Install OPA Gatekeeper and Ratify"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-ratify",children:"Configure Ratify"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploy-container-images-in-aks",children:"Deploy container images in AKS"})}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"Please note that the examples and commands provided in this document are specifically designed for the Linux operating system."}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Create or use an ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/container-registry/container-registry-get-started-azure-cli",children:"ACR"})," for storing container images and signatures"]}),"\n",(0,s.jsxs)(n.li,{children:["Create or use an ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/key-vault/general/quick-create-cli",children:"AKV"})," for storing keys and certificates"]}),"\n",(0,s.jsxs)(n.li,{children:["Create or use an ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/learn/quick-kubernetes-deploy-cli",children:"AKS"})," for deploying container images"]}),"\n",(0,s.jsxs)(n.li,{children:["Install ",(0,s.jsx)(n.a,{href:"https://docs.sigstore.dev/system_config/installation/",children:"Cosign"})," for signing container images with Cosign signatures"]}),"\n",(0,s.jsxs)(n.li,{children:["Install ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us
1/azure/container-registry/container-registry-tutorial-sign-build-push#install-notation-cli-and-akv-plugin",children:"Notation and Notation AKV plugin"})," for signing container images with Notary Project signatures"]}),"\n",(0,s.jsxs)(n.li,{children:["Install and configure the latest ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/cli/azure/install-azure-cli",children:"Azure CLI"}),", or run commands in the ",(0,s.jsx)(n.a,{href:"https://portal.azure.com/#cloudshell/",children:"Azure Cloud Shell"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"configure-environment-variables",children:"Configure environment variables"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'# Azure related variables\nexport TENANT_ID=<your Tenant ID>\nexport SUB_ID=<your subscription id>\n# AKV related variables\nexport AKV_RG=<your AKV resource group>\nexport AKV_NAME=<your AKV name>\n# ACR related variables\nexport ACR_RG=<your ACR resource group>\nexport ACR_NAME=<your ACR name>\nexport IMAGE_SIGNED="$ACR_NAME.azurecr.io/ratify-demo/net-monitor:v1"\nexport IMAGE_SIGNED_SOURCE=https://github.com/wabbit-networks/net-monitor.git#main\nexport IMAGE_UNSIGNED="$ACR_NAME.azurecr.io/ratify-demo/net-watcher:v1"\nexport IMAGE_UNSIGNED_SOURCE=https://github.com/wabbit-networks/net-watcher.git#main\n# Workload identity used by Ratify to access ACR and AKV\nexport IDENTITY_NAME=<name of the identity to be created>\nexport IDENTITY_RG=<your identity resource group name>\n# AKS related variables\nexport AKS_RG=<your AKS resource group>\nexport AKS_NAME=<your AKS name>\nexport RATIFY_NAMESPACE="gatekeeper-system"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"prepare-container-images-in-acr",children:"Prepare container images in ACR"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"You can skip this section if you already built and pushed images to ACR."}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Sign in with Azure CLI"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"az login\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To learn more about Azure CLI and how to sign in with it, see ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"Sign in with Azure CLI"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Ensure the logged-in identity has both ",(0,s.jsx)(n.code,{children:"acrpush"})," and ",(0,s.jsx)(n.code,{children:"acrpull"})," roles assigned."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'export USER_OBJECT_ID="$(az ad signed-in-user show --query id -o tsv)"\naz role assignment create \\\n --assignee-object-id ${USER_OBJECT_ID} \\\n --role acrpull --role acrpush \\\n --scope subscriptions/${SUB_ID}/resourceGroups/${ACR_RG}/providers/Microsoft.ContainerRegistry/registries/${ACR_NAME}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Log into ACR"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"az acr login --name ${ACR_NAME}\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Build and push an image that will be signed in later steps."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"az acr build -r ${ACR_NAME} -t ${IMAGE_SIGNED} ${IMAGE_SIGNED_SOURCE} --no-logs\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Build and push an image that will not be signed"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"az acr build -r ${ACR_NAME} -t ${IMAGE_UNSIGNED} ${IMAGE_UNSIGNED_SOURCE} --no-logs\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"sign-container-images-in-acr",children:"Sign container images in ACR"}),"\n",(0,s.jsx)(n.p,{children:"Notation and Cosign are two options for signing container images. They produce different kinds of signatures and store them in the ACR. Depending on the tool you use, you need to configure Ratify accordingly to verify the signatures from each tool."}
1),"\n",(0,s.jsx)(n.p,{children:"You can skip this section if you have already used Notation or Cosign to sign your container images in ACR."}),"\n",(0,s.jsx)(n.h3,{id:"use-notation-with-certificates-stored-in-akv",children:"Use Notation with certificates stored in AKV"}),"\n",(0,s.jsx)(n.p,{children:"Depending on the type of certificates you use, you can refer to different documents to sign container images with Notation and AKV."}),"\n",(0,s.jsxs)(n.p,{children:["For self-signed certificates, see ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/container-registry/container-registry-tutorial-sign-build-push",children:"Sign container images with Notation and Azure Key Vault using a self-signed certificate"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["For CA issued certificates, see ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/container-registry/container-registry-tutorial-sign-trusted-ca",children:"Sign container images with Notation and Azure Key Vault using a CA issued certificate"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["As a result, the image named ",(0,s.jsx)(n.code,{children:"${IMAGE_SIGNED}"})," should be signed successfully with Notation and AKV. Configure the following environment variables for later usage."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"export CERT_NAME=<name of signing/leaf certificate>\nexport SUBJECT_DN=<subject DN of the signing/leaf certificate>\nexport CERT_KEY_ID=<key identity for the signing/leaf certificate>\n"})}),"\n",(0,s.jsx)(n.h3,{id:"use-cosign-with-keys-stored-in-akv",children:"Use Cosign with keys stored in AKV"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Configure environment variables"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"# The key used for Cosign signing\nexport KEY_NAME=<name of the key to be created for Cosign signing>\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Log into Azure"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"az login\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Assign role ",(0,s.jsx)(n.code,{children:"Key Vault Crypto Officer"})," to logged in identity for creating a key"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'export USER_OBJECT_ID="$(az ad signed-in-user show --query id -o tsv)"\naz role assignment create --role "Key Vault Crypto Officer" --assignee ${USER_OBJECT_ID} \\\n--scope "/subscriptions/${SUB_ID}/resourceGroups/${AKV_RG}/providers/Microsoft.KeyVault/vaults/${AKV_NAME}"\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Create a key in your AKV"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"az keyvault key create --vault-name ${AKV_NAME} -n ${KEY_NAME} --protection software\n"})}),"\n",(0,s.jsx)(n.p,{children:"Get the key id and retrieve the key version:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'az keyvault key show --name ${KEY_NAME} --vault-name ${AKV_NAME} --query "key.kid"\n'})}),"\n",(0,s.jsx)(n.p,{children:"An example output:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-text",children:"https://<your akv name>.vault.azure.net/keys/<your key name>/<your key version>\n"})}),"\n",(0,s.jsx)(n.p,{children:"Configure an environment variable for the version for later usage."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"export KEY_VER=<your key version>\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Sign an image stored in your ACR"}),"\n",(0,s.jsx)(n.p,{children:"Confirm no signatures before signing"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"cosign tree ${IMAGE_SIGNED}\n"})}),"\n",(0,s.jsx)(n.p,{children:"Sign the image"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"cosign sign --key azurekms://$AKV_NAME.vault.azure.net/${KEY_NAME}/${KEY_VER} --tlog-upload=false ${IMAGE_SIGNED}\n"})}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["In this article, use flag ",(0,s.jsx)(n.code,{children:"--tlog-upload=false"})," to skip upload the signature to the transparent log (Rekor by default)."]}),"\n",(0,s.jsxs)(n.p,{children:["Sign using a key in AKV does not necessarily require the role ",(0,s.jsx)(n.code,{children:"Key Vault Crypto Officer"}),", you can use another identity and assign the role ",(0,s.jsx)(n.code,{children:"Key Vault Crypto User"})," for signing action only."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Confirm the signature is pushed and associated with the image in ACR"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"cosign tree ${IMAGE_SIGNED}\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"set-up-an-azure-workload-identity",children:"Set up an Azure workload identity"}),"\n",(0,s.jsxs)(n.p,{children:["Ratify pulls artifacts from an ACR using Workload Federated Identity in an AKS cluster. For an overview on how workload identity operates in Azure, refer to the ",(0,s.jsx)(n.a,{href:"https://docs.microsoft.com/en-us
1/azure/active-directory/develop/workload-identity-federation",children:"documentation"}),". You can use workload identity federation to configure an Azure AD app registration or user-assigned managed identity. The following workflow includes the Workload Identity configuration."]}),"\n",(0,s.jsx)(n.h3,{id:"create-a-workload-federated-identity",children:"Create a Workload Federated Identity."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'az identity create --name "${IDENTITY_NAME}" --resource-group "${IDENTITY_RG}" --location "${LOCATION}" --subscription "${SUB_ID}"\n\nexport IDENTITY_OBJECT_ID="$(az identity show --name "${IDENTITY_NAME}" --resource-group "${IDENTITY_RG}" --query \'principalId\' -otsv)"\nexport IDENTITY_CLIENT_ID=$(az identity show --name ${IDENTITY_NAME} --resource-group ${IDENTITY_RG} --query \'clientId\' -o tsv)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"authoring-access-to-acr",children:"Authoring access to ACR"}),"\n",(0,s.jsxs)(n.p,{children:["Configure the user-assigned managed identity and assign ",(0,s.jsx)(n.code,{children:"AcrPull"})," role to the workload identity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"az role assignment create \\\n --assignee-object-id ${IDENTITY_OBJECT_ID} \\\n --role acrpull \\\n --scope subscriptions/${SUB_ID}/resourceGroups/${ACR_RG}/providers/Microsoft.ContainerRegistry/registries/${ACR_NAME}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"authoring-access-to-akv",children:"Authoring access to AKV"}),"\n",(0,s.jsx)(n.h4,{id:"image-signed-with-notation-and-certificates-in-akv",children:"Image signed with Notation and certificates in AKV"}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["Ratify requires secret permissions to retrieve the root CA certificate from the entire certificate chain,\nplease set private keys to Non-exportable at certificate creation time to avoid security risk. Learn more about non-exportable keys ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/key-vault/certificates/how-to-export-certificate?tabs=azure-cli#exportable-and-non-exportable-keys",children:"here"})]}),"\n",(0,s.jsxs)(n.p,{children:["For security or other reasons (such as you are from a different organization), you may not be able to access AKV and get the root CA certificates. In that case, you can use the ",(0,s.jsx)(n.a,{href:"/docs/1.2/reference/custom%20resources/certificate-stores#inline-certificate-provider",children:"inline certificate provider"})," to specify the root CA certificate value directly, without needing AKV."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Assign ",(0,s.jsx)(n.code,{children:"Key Vault Secrets User"})," role to this identity for accessing AKV"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'az role assignment create --role "Key Vault Secrets User" --assignee ${IDENTITY_OBJECT_ID} \\\n--scope "/subscriptions/${SUB_ID}/resourceGroups/${AKV_RG}/providers/Microsoft.KeyVault/vaults/${AKV_NAME}"\n'})}),"\n",(0,s.jsx)(n.h4,{id:"images-signed-with-cosign-and-keys-in-akv",children:"Images signed with Cosign and keys in AKV"}),"\n",(0,s.jsxs)(n.p,{children:["Assign ",(0,s.jsx)(n.code,{children:"Key Vault Crypto User"})," role to this identity for accessing AKV"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'az role assignment create --role "Key Vault Crypto User" --assignee $IDENTITY_OBJECT_ID \\\n--scope "/subscriptions/${SUB_ID}/resourceGroups/${AKV_RG}/providers/Microsoft.KeyVault/vaults/${AKV_NAME}"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"set-up-your-aks-cluster",children:"Set up your AKS cluster"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Create an OIDC enabled AKS cluster. You can skip this step if you have an AKS cluster with both OIDC and workload identity enabled."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'# Install the aks-preview extension\naz extension add --name aks-preview\n\n# Register the \'EnableWorkloadIdentityPreview\' feature flag\naz feature register --namespace "Microsoft.ContainerService" --name "EnableWorkloadIdentityPreview"\naz provider register --namespace Microsoft.ContainerService\n\naz aks create \\\n --resource-group "${AKS_RG}" \\\n --name "${AKS_NAME}" \\\n --node-vm-size Standard_DS3_v2 \\\n --node-count 1 \\\n --generate-ssh-keys \\\n --enable-workload-identity \\\n --attach-acr ${ACR_NAME} \\\n --enable-oidc-issuer\n\n# Connect to the AKS cluster:\naz aks get-credentials --resource-group ${AKS_RG} --name ${AKS_NAME}\n\nexport AKS_OIDC_ISSUER="$(az aks show -n ${AKS_NAME} -g ${AKS_RG} --query "oidcIssuerProfile.issuerUrl" -otsv)"\n'})}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["The official steps for setting up Workload Identity on AKS can be found ",(0,s.jsx)(n.a,{href:"https://azure.github.io/azure-workload-identity/docs/quick-start.html",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"This step above may take around 10 minutes to complete. The registration status can be checked by running the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'az feature show --namespace "Microsoft.ContainerService" --name "EnableWorkloadIdentityPreview" -o table\nName RegistrationState\n-------------------------------------------------------- -------------------\nMicrosoft.ContainerService/EnableWorkloadIdentityPreview Registered\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Update an existing AKS cluster with OIDC and workload identity enabled. You can skip this
1step if you have an AKS cluster with both OIDC and workload identity enabled."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'az aks update -g ${AKS_RG} -n ${AKS_NAME} --enable-oidc-issuer --enable-workload-identity\nexport AKS_OIDC_ISSUER="$(az aks show -n ${AKS_NAME} -g ${AKS_RG} --query "oidcIssuerProfile.issuerUrl" -otsv)"\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Establish federated identity credential for namespace ",(0,s.jsx)(n.code,{children:"${RATIFY_NAMESPACE}"})," where you deploy Ratify:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'az identity federated-credential create \\\n--name ratify-federated-credential \\\n--identity-name "${IDENTITY_NAME}" \\\n--resource-group "${IDENTITY_RG}" \\\n--issuer "${AKS_OIDC_ISSUER}" \\\n--subject system:serviceaccount:"${RATIFY_NAMESPACE}":"ratify-admin"\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"install-gatekeeper-and-ratify-in-aks",children:"Install Gatekeeper and Ratify in AKS"}),"\n",(0,s.jsxs)(n.p,{children:["Run ",(0,s.jsx)(n.code,{children:'az aks show -g "${AKS_RG}" -n "${AKS_NAME}" --query addonProfiles.azurepolicy'})," to verify if the AKS cluster has azure policy addon enabled, learn more at ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/use-azure-policy",children:"use azure policy"})]}),"\n",(0,s.jsx)(n.h3,{id:"when-azure-policy-addon-is-not-enabled",children:"When Azure Policy Addon is not enabled"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Install Gatekeeper from helm chart:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts\n\nhelm install gatekeeper/gatekeeper \\\n--name-template=gatekeeper \\\n--namespace gatekeeper-system --create-namespace \\\n--set enableExternalData=true \\\n--set validatingWebhookTimeoutSeconds=5 \\\n--set mutatingWebhookTimeoutSeconds=2 \\\n--set externaldataProviderResponseCacheTTL=10s\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Install Ratify on AKS from helm chart:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"# Add a Helm repo\nhelm repo add ratify https://notaryproject.github.io/ratify\n\n# Install Ratify\nhelm install ratify \\\n ratify/ratify --atomic \\\n --namespace ${RATIFY_NAMESPACE} --create-namespace \\\n --set featureFlags.RATIFY_CERT_ROTATION=true \\\n --set azureWorkloadIdentity.clientId=${IDENTITY_CLIENT_ID}\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Enforce Gatekeeper policy to allow only signed images can be deployed on AKS:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://notaryproject.github.io/ratify/library/default/template.yaml\nkubectl apply -f https://notaryproject.github.io/ratify/library/default/samples/constraint.yaml\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"when-azure-policy-addon-is-enabled-on-aks",children:"When Azure Policy Addon is enabled on AKS"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ensure your AKS cluster is 1.26+"}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run ",(0,s.jsx)(n.code,{children:"az feature register -n AKS-AzurePolicyExternalData --namespace Microsoft.ContainerService"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Install Ratify on AKS from helm chart:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"# Add a Helm repo\nhelm repo add ratify https://notaryproject.github.io/ratify\nhelm repo update\n\n# Install Ratify\nhelm install ratify \\\n ratify/ratify --atomic \\\n --namespace gatekeeper-system --create-namespace \\\n --set provider.enableMutation=false \\\n --set featureFlags.RATIFY_CERT_ROTATION=true \\\n --set azureWorkloadIdentity.clientId=${IDENTITY_CLIENT_ID}\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Create and assign azure policy on your cluster:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'export CUSTOM_POLICY=$(curl -L https://raw.githubusercontent.com/deislabs/ratify/main/library/default/customazurepolicy.json)\nexport DEFINITION_NAME="ratify-default-custom-policy"\nexport POLICY_SCOPE=$(az aks show -g "${AKS_RG}" -n "${AKS_NAME}" --query id -o tsv)\n\nexport DEFINITION_ID=$(az policy definition create --name "${DEFINITION_NAME}" --rules "$(echo "${CUSTOM_POLICY}" | jq .policyRule)" --params "$(echo "${CUSTOM_POLICY}" | jq .parameters)" --mode "Microsoft.Kubernetes.Data" --query id -o tsv)\n\nexport ASSIGNMENT_ID=$(az policy assignment create --policy "${DEFINITION_ID}" --name "${DEFINITION_NAME}" --scope "${POLICY_SCOPE}" --query id -o tsv)\n\necho "Please wait policy assignment with id ${ASSIGNMENT_ID} taking effect"\necho "It often requires 15 min"\necho "You can run \'kubectl get constraintTemplate ratifyverification\' to verify the policy takes effect"\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"configure-ratify",children:"Configure Ratify"}),"\n",(0,s.jsx)(n.h3,{id:"create-a-custom-resource-for-accessing-acr",children:"Create a custom resource for accessing ACR"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create a configuration file for a ",(0,s.jsx)(n.code,{children:"Store"})," custom resource named ",(0,s.jsx)(n.code,{children:"store-oras"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"cat <<EOF > store_config.yaml\napiVersion: config.ratify.deislabs.io/v1beta1\nkind: Store\
1nmetadata:\n name: store-oras\nspec:\n name: oras\n parameters:\n authProvider:\n name: azureWorkloadIdentity\n clientID: ${IDENTITY_CLIENT_ID}\n cosignEnabled: true\nEOF\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Apply the configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f store_config.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Confirm the configuration is applied successful."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl get Store store-oras\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Make sure the ",(0,s.jsx)(n.code,{children:"ISSUCCESS"})," value is true in the results of above three commands. If it is not, you need to check the detailed error logs by using ",(0,s.jsx)(n.code,{children:"kubectl describe"})," commands. For example,"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl describe Store store-oras\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"create-a-custom-resource-for-accessing-akv",children:"Create a custom resource for accessing AKV"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create a configuration file for a ",(0,s.jsx)(n.code,{children:"keymanagementprovider"})," custom resource named ",(0,s.jsx)(n.code,{children:"keymanagementprovider-akv"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"For verifying images signed with Notation using certificates in AKV, create the following configuration:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"cat <<EOF > kmp_config.yaml\napiVersion: config.ratify.deislabs.io/v1beta1\nkind: KeyManagementProvider\nmetadata:\n name: keymanagementprovider-akv\nspec:\n type: azurekeyvault\n parameters:\n vaultURI: https://${AKV_NAME}.vault.azure.net/\n certificates:\n - name: ${CERT_NAME}\n version: ${CERT_KEY_ID}\n tenantID: ${TENANT_ID}\n clientID: ${IDENTITY_CLIENT_ID}\nEOF\n"})}),"\n",(0,s.jsx)(n.p,{children:"For verifying images signed with Cosign using keys in AKV, create the following configuration:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"cat <<EOF > kmp_config.yaml\napiVersion: config.ratify.deislabs.io/v1beta1\nkind: KeyManagementProvider\nmetadata:\n name: keymanagementprovider-akv\nspec:\n type: azurekeyvault\n parameters:\n vaultURI: https://${AKV_NAME}.vault.azure.net/\n keys:\n - name: ${KEY_NAME}\n version: ${KEY_VER}\n tenantID: ${TENANT_ID}\n clientID: ${IDENTITY_CLIENT_ID}\nEOF\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["You may combine the configuration into one ",(0,s.jsx)(n.code,{children:"KeyManagementProvider"})," resource for both keys and certificates if they are stored in the same AKV."]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Apply the configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f kmp_config.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Confirm the configuration is applied successful."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl get KeyManagementProvider keymanagementprovider-akv\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Make sure the ",(0,s.jsx)(n.code,{children:"ISSUCCESS"})," value is true in the results of above three commands. If it is not, you need to check the detailed error logs by using ",(0,s.jsx)(n.code,{children:"kubectl describe"})," commands. For example,"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl describe KeyManagementProvider keymanagementprovider-akv\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"configure-the-notation-verifier-resource-for-verifying-images-signed-with-notation",children:"Configure the Notation verifier resource for verifying images signed with Notation"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create a configuration file for a ",(0,s.jsx)(n.code,{children:"Verifier"})," custom resource named ",(0,s.jsx)(n.code,{children:"verifier-notation"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'cat <<EOF > notation_config.yaml\napiVersion: config.ratify.deislabs.io/v1beta1\nkind: Verifier\nmetadata:\n name: verifier-notation\nspec:\n name: notation\n artifactTypes: a
1pplication/vnd.cncf.notary.signature\n parameters:\n verificationCertStores:\n certs:\n - keymanagementprovider-akv\n trustPolicyDoc:\n version: "1.0"\n trustPolicies:\n - name: default\n registryScopes:\n - "*"\n signatureVerification:\n level: strict\n trustStores:\n - ca:certs\n trustedIdentities:\n - "x509.subject: ${SUBJECT_DN}"\nEOF\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Apply the configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f notation_config.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Confirm the configuration is applied successful."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl get Verifier verifier-notation\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Make sure the ",(0,s.jsx)(n.code,{children:"ISSUCCESS"})," value is true in the results of above three commands. If it is not, you need to check the detailed error logs by using ",(0,s.jsx)(n.code,{children:"kubectl describe"})," commands. For example,"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl describe Verifier verifier-notation\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"configuration-for-images-signed-with-cosign-using-keys-in-akv",children:"Configuration for images signed with Cosign using keys in AKV"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Create a configuration file for a ",(0,s.jsx)(n.code,{children:"Verifier"})," custom resource named ",(0,s.jsx)(n.code,{children:"verifier-cosign"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'cat <<EOF > cosign_config.yaml\napiVersion: config.ratify.deislabs.io/v1beta1\nkind: Verifier\nmetadata:\n name: verifier-cosign\nspec:\n name: cosign\n artifactTypes: application/vnd.dev.cosign.artifact.sig.v1+json\n parameters:\n trustPolicies:\n - name: default\n scopes:\n - "*"\n keys:\n - provider: keymanagementprovider-akv\nEOF\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Apply the verification configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f cosign_config.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Confirm the configuration is applied successful."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl get Verifier verifier-cosign\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Make sure the ",(0,s.jsx)(n.code,{children:"ISSUCCESS"})," value is true in the results of above three commands. If it is not, you need to check the detailed error logs by using ",(0,s.jsx)(n.code,{children:"kubectl describe"})," commands. For example,"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl describe Verifier verifier-cosign\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deploy-container-images-in-aks",children:"Deploy container images in AKS"}),"\n",(0,s.jsx)(n.p,{children:"Run the following command, since $IMAGE_SIGNED is signed with the key configured in Ratify, so this image was allowed for deployment after signature verification succeeded."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl run demo-signed --image=$IMAGE_SIGNED\n"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command, since $IMAGE_UNSIGNED is not signed, so this image was NOT allowed for deployment."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl run demo-unsigned --image=$IMAGE_UNSIGNED\n"})}),"\n",(0,s.jsx)(n.h2,{id:"other-scenarios",children:"Other scenarios"}),"\n",(0,s.jsx)(n.h3,{id:"fine-tuned-trust-policy-for-cosign-verifier",children:"Fine-tuned trust policy for Cosign verifier"}),"\n",(0,s.jsxs)(n.p,{children:["You can configure different trust policies for images from various registry scope for the Cosign verifier. For example, you have two ACR: ",(0,s.jsx)(n.code,{children:"$ACR_NAME1"})," and ",(0,s.jsx)(n.code,{children:"$ACR_NAME2"}),". For ",(0,s.jsx)(n.code,{children:"$ACR_NAME1"}),", you want to use ",(0,s.jsx)(n.code,{children:"keymanagementprovider-akv1"})," resource, For ",(0,s.jsx)(n.code,{children:"$ACR_NAME2"}),", you want to use ",(0,s.jsx)(n.code,{children:"keymanagementprovider-akv2"})," resource. You can update Cosign Verifier resource as the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: config.ratify.deislabs.io/v1beta1\nkind: Verifier\nmetadata:\n name: verifier-cosign\nspec:\n name: cosign\n artifactTypes: a
1pplication/vnd.dev.cosign.artifact.sig.v1+json\n parameters:\n trustPolicies:\n - name: $ACR_NAME1\n scopes:\n - "$ACR_NAME1.azurecr.io/*"\n keys:\n - provider: keymanagementprovider-akv1\n - name: $ACR_NAME2\n scopes:\n - "$ACR_NAME2.azurecr.io/*"\n keys:\n - provider: keymanagementprovider-akv2\n'})}),"\n",(0,s.jsxs)(n.p,{children:["For more information, please refer to the ",(0,s.jsx)(n.a,{href:"/docs/1.2/plugins/verifier/cosign#scopes",children:"scopes of Cosign verifier"})," ."]}),"\n",(0,s.jsx)(n.h3,{id:"rotate-the-key-used-by-cosign",children:"Rotate the key used by Cosign"}),"\n",(0,s.jsxs)(n.p,{children:["Keys in AKV may be rotated regularly as security best practice. If the key is rotated with a new version, you can update the ",(0,s.jsx)(n.code,{children:"KeyManagementProvider"})," resource by adding the new version of the key, as Ratify (v1.2.0 or before) does not support reconciling key resources regularly. For example, if the new version of key is set to environment variable ",(0,s.jsx)(n.code,{children:"$KEY_VER_NEW"}),", you can do the following:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Add the new key ",(0,s.jsx)(n.code,{children:"$KEY_VER_NEW"})," for ",(0,s.jsx)(n.code,{children:"KeyManagementProvider"})," resource"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: config.ratify.deislabs.io/v1beta1\nkind: KeyManagementProvider\nmetadata:\n name: keymanagementprovider-akv\nspec:\n type: azurekeyvault\n parameters:\n vaultURI: https://$AKV_NAME.vault.azure.net/\n keys:\n - name: $KEY_NAME\n version: $KEY_VER \n version: $KEY_VER_NEW\n tenantID: $TENANT_ID\n clientID: $CLIENT_ID\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Apply the new configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f verification_config.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Confirm the new configuration is applied successfully"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl get KeyManagementProvider keymanagementprovider-akv\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"disable-the-specific-version-of-key-used-by-cosign",children:"Disable the specific version of key used by Cosign"}),"\n",(0,s.jsxs)(n.p,{children:["In some cases, you may need to disable a specific version of key. For example, the specific version of key is leaked. So, images signed using the specific version of key should not be trusted and the deployment of those images should be denied. As Ratify (v1.2.0 or before) does not support reconciling key resources regularly, so you need to manually remove the version of key from ",(0,s.jsx)(n.code,{children:"KeyManagementProvider"})," resource. For example, if version ",(0,s.jsx)(n.code,{children:"$KEY_VER"})," is leaked, what you need to do is:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Disable the specific version from AKV, in this case, version ",(0,s.jsx)(n.code,{children:"$KEY_VER"})," is disabled."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Rotate the key to a new version ",(0,s.jsx)(n.code,{children:"$KEY_VER_NEW"}),", so that your images will be signed with new version."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Update ",(0,s.jsx)(n.code,{children:"KeyManagementProvider"})," resource to add the new version of key and remove the disabled version"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"KeyManagementProvider"})," resource will look like the following as disabled version ",(0,s.jsx)(n.code,{children:"$KEY_VER"})," was removed."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"apiVersion: config.ratify.deislabs.io/v1beta1\nkind: KeyManagementProvider\nmetadata:\n name: keymanagementprovider-akv\nspec:\n type: azurekeyvault\n parameters:\n vaultURI: https://$AKV_NAME.vault.azure.net/\n keys:\n - name: $KEY_NAME\n version: $KEY_VER_NEW\n tenantID: $TENANT_ID\n clientID: $CLIENT_ID\n"})}),"\n",(0,s.jsx)(n.p,{children:"Apply the new configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f verification_config.yaml\n"})}),"\n",(0,s.jsx)(n.p,{children:"Confirm the new configuration is applied successfully"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl get KeyManagementProvider keymanagementprovider-akv\n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.