# Use Ratify to validate image before deployment in AKS ## Prerequisite Complete the steps in [Build, Sign and Verify a container image using notation and certificate in Azure Key Vault](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-tutorial-sign-build-push) ## Create a new ACR ```console ACR_NAME=<ACR Name> ACR_RG=<ACR Resource Group Name> az acr create -n $ACR_NAME -g $ACR_RG --sku Standard az acr update --name $ACR_NAME --anonymous-pull-enabled ``` ## Create a new AKS cluster and integrate with an existing ACR ```console AKS_NAME=<AKS Name> AKS_RG=<AKS Resource Group Name> az aks create -n $AKS_NAME -g $AKS_RG --generate-ssh-keys --attach-acr $ACR_NAME ``` > NOTE: See [here](https://learn.microsoft.com/en-us/azure/aks/cluster-container-registry-integration?toc=%2Fazure%2Fcontainer-registry%2Ftoc.json&bc=%2Fazure%2Fcontainer-registry%2Fbreadcrumb%2Ftoc.json&tabs=azure-cli#configure-acr-integration-for-existing-aks-clusters) to configure ACR integration for existing AKS clusters. ## Set up Workload Identity with AKS and ACR ### Update AKS cluster with OIDC issuer ```console az aks update -n $AKS_NAME -g $AKS_RG --enable-oidc-issuer export SERVICE_ACCOUNT_ISSUER="$(az aks show -g $AKS_RG -n $AKS_NAME --query "oidcIssuerProfile.issuerUrl" -otsv)" export SUBSCRIPTION_ID=xxx-xxx-xxx-xxx export AZURE_TENANT_ID="$(az account show -s $SUBSCRIPTION_ID --query tenantId -otsv)" ``` ### Connect to AKS ```console az aks get-credentials -n $AKS_NAME -g $AKS_RG ``` ### Install Workload Identity ```console helm repo add azure-workload-identity https://azure.github.io/azure-workload-identity/charts helm repo update helm install workload-identity-webhook azure-workload-identity/workload-identity-webhook \ --namespace azure-workload-identity-system \ --create-namespace \ --set azureTenantID="${AZURE_TENANT_ID}" ``` ## Create ACR AAD application ```console export APPLICATION_NAME=ratify_test az ad sp create-for-rbac --name $APPLICATION_NAME export APPLICATION_CLIENT_ID="$(az ad sp list --display-name "${APPLICATION_NAME}" --query '[0].appId' -otsv)" az role assignment create --assignee ${APPLICATION_CLIENT_ID} --role acrpull --scope subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${ACR_RG}/providers/Microsoft.ContainerRegistry/registries/${ACR_NAME} ``` ## Configure service account ```console export RATIFY_NS=ratify-service export RATIFY_SA=ratify-admin export APPLICATION_OBJECT_ID="$(az ad app show --id ${APPLICATION_CLIENT_ID} --query id -otsv)" ``` ```console cat <<EOF > body.json { "name": "kubernetes-federated-credential", "issuer": "${SERVICE_ACCOUNT_ISSUER}", "subject": "system:serviceaccount:${RATIFY_NS}:${RATIFY_SA}", "description": "Kubernetes service account federated credential", "audiences": [ "api://AzureADTokenExchange" ] } EOF ``` ```console az rest --method POST --uri "https://graph.microsoft.com/beta/applications/${APPLICATION_OBJECT_ID}/federatedIdentityCredentials" --body @body.json ``` ## Install Gatekeeper ```console helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts helm install gatekeeper/gatekeeper \ --name-template=gatekeeper \ --namespace gatekeeper-system --create-namespace \ --set enableExternalData=true \ --set validatingWebhookTimeoutSeconds=7 ``` ## Install Ratify >NOTE: Public key used for notation sign, see [notation sign using AKV](https://hackmd.io/@yizha1/notation-sign-verify) ```console export KEY_NAME=wabbit-networks-io export AKV_NAME=wabbitakv export PUBLIC_KEY=$(az keyvault certificate show -n $KEY_NAME \ --vault-name $AKV_NAME \ -o json | jq -r '.cer' | base64 -d | openssl x509 -inform DER) ``` ```console helm install ratify ratify/ratify --namespace ${RATIFY_NS} --create-namespace \ --set ratifyTestCert="${PUBLIC_KEY}" \ --set azureWorkloadIdentity.clientId=${APPLICATION_CLIENT_ID} \ --set oras.authProviders.azureWorkloadIdentityEnabled=true --atomic kubectl apply -f https://deislabs.github.io/ratify/library/default/template.yaml kubectl apply -f https://deislabs.github.io/ratify/library/default/samples/constraint.yaml ``` ## Deploy signed image ```console kubectl run net-monitor --image=$IMAGE ``` ## Deploy un-signed image ```console kubectl run net-monitor --image=$IMAGE-unsigned ``` ## Clean up ```consle helm uninstall ratify --namespace ratify-service kubectl delete -f https://deislabs.github.io/ratify/library/default/template.yaml kubectl delete -f https://deislabs.github.io/ratify/library/default/samples/constraint.yaml helm uninstall gatekeeper/gatekeeper --namespace gatekeeper-system # for helm3 kubectl delete crd -l gatekeeper.sh/system=yes ``` ## Reference 1. [oras-auth-provider.md](https://github.com/deislabs/ratify/blob/main/docs/reference/oras-auth-provider.md#2-azure-workload-identity) 2. [nv2-sign-verify-aks](https://github.com/Azure/notation-azure-kv/blob/main/docs/nv2-sign-verify-aks.md)