# 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)