Repository: ratify-project/ratify
Pull request #1533 (2024-05-31 21:32:52)

chore: merge dev into main 6-6-24
# Description

## What this PR does / why we need it:
merge recent dev changes into main branch

## Which issue(s) this PR fixes *(optional, using `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when the PR gets merged)*:
Fixes #

## Type of change

Please delete options that are not relevant.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Helm Chart Change (any edit/addition/update that is necessary for changes merged to the `main` branch)
- [ ] This change requires a documentation update

# How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Please also list any relevant details for your test configuration

- [ ] Test A
- [ ] Test B

# Checklist:

- [ ] Does the affected code have corresponding tests?
- [ ] Are the changes documented, not just with inline documentation, but also with conceptual documentation such as an overview of a new feature, or task-based documentation like a tutorial? Consider if this change should be announced on your project blog.
- [ ] Does this introduce breaking changes that would require an announcement or bumping the major version?
- [ ] Do all new files have appropriate license header?

# Post Merge Requirements
- [ ] MAINTAINERS: manually trigger the "Publish Package" workflow after merging any PR that indicates `Helm Chart Change`



Patch:
diff --git a/.github/codecov.yml b/.github/codecov.yml
index 193437e..cbfef64 100644
--- a/.github/codecov.yml
+++ b/.github/codecov.yml
@@ -1,2 +1,7 @@
 ignore:
-  - "./api"  # ignore folders and all its contents
\ No newline at end of file
+  - "./api"  # ignore folders and all its contents
+coverage:
+  status:
+    patch:
+      default:
+        target: 80%
\ No newline at end of file
diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml
index a929c8a..b9935f4 100644
--- a/.github/workflows/build-pr.yml
+++ b/.github/workflows/build-pr.yml
@@ -23,7 +23,7 @@ jobs:
       fail-fast: false
       matrix:
         KUBERNETES_VERSION: ["1.29.2"]
-        GATEKEEPER_VERSION: ["3.15.0"]
+        GATEKEEPER_VERSION: ["3.16.0"]
     uses: ./.github/workflows/e2e-k8s.yml 
     with:
       k8s_version: ${{ matrix.KUBERNETES_VERSION }}
@@ -36,7 +36,7 @@ jobs:
       fail-fast: false
       matrix:
         KUBERNETES_VERSION: ["1.28.7", "1.29.2"]
-        GATEKEEPER_VERSION: ["3.13.0", "3.14.0", "3.15.0"]
+        GATEKEEPER_VERSION: ["3.14.0", "3.15.0", "3.16.0"]
     uses: ./.github/workflows/e2e-k8s.yml 
     with:
       k8s_version: ${{ matrix.KUBERNETES_VERSION }}
@@ -52,7 +52,7 @@ jobs:
       fail-fast: false
       matrix:
         KUBERNETES_VERSION: ["1.27.9", "1.29.2"]
-        GATEKEEPER_VERSION: ["3.13.0", "3.14.0", "3.15.0"]
+        GATEKEEPER_VERSION: ["3.14.0", "3.15.0", "3.16.0"]
     uses: ./.github/workflows/e2e-aks.yml
     with:
       k8s_version: ${{ matrix.KUBERNETES_VERSION }}
@@ -79,7 +79,7 @@ jobs:
           go-version: '1.21'
 
       - name: Az CLI login
-        uses: azure/login@6b2456866fc08b011acb422a92a4aa20e2c4de32 # v2.1.0
+        uses: azure/login@6c251865b4e6290e7b78be643ea2d005bc51f69a # v2.1.1
         with:
           client-id: ${{ env.AZURE_CLIENT_ID }}
           tenant-id: ${{ env.AZURE_TENANT_ID }}
diff --git a/.github/workflows/clean-dev-package.yml b/.github/workflows/clean-dev-package.yml
new file mode 100644
index 0000000..f21baa6
--- /dev/null
+++ b/.github/workflows/clean-dev-package.yml
@@ -0,0 +1,28 @@
+name: clean-dev-package
+
+on:
+  workflow_dispatch:
+
+permissions:
+  contents: read
+
+jobs:
+  cleanup-packages:
+    runs-on: ubuntu-latest
+    permissions:
+        packages: write
+    steps:
+      - name: Clean up ratify-crds-dev
+        uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0
+        with: 
+          package-name: 'ratify-crds-dev'
+          package-type: 'container'
+          min-versions-to-keep: 7
+          delete-only-pre-release-versions: "true"
+      - name: Clean up ratify-dev
+        uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0
+        with: 
+          package-name: 'ratify-dev'
+          package-type: 'container'
+          min-versions-to-keep: 7
+          delete-only-pre-release-versions: "true"
\ No newline at end of file
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 32b7786..9cfe097 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -33,7 +33,7 @@ jobs:
         with:
           go-version: "1.21"
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@9fdb3e49720b44c48891d036bb502feb25684276 # tag=v3.25.6
+        uses: github/codeql-action/init@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # tag=v3.25.8
         with:
           languages: go
       - name: Run tidy
@@ -41,4 +41,4 @@ jobs:
       - name: Build CLI
         run: make build
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@9fdb3e49720b44c48891d036bb502feb25684276 # tag=v3.25.6
+        uses: github/codeql-action/analyze@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # tag=v3.25.8
diff --git a/.github/workflows/publish-dev-assets.yml b/.github/workflows/publish-dev-assets.yml
index c4c15d7..0697e51 100644
--- a/.github/workflows/publish-dev-assets.yml
+++ b/.github/workflows/publish-dev-assets.yml
@@ -37,7 +37,7 @@ jobs:
           echo ::set-output name=baseref::${REPOSITORYBASE}
           echo ::set-output name=crdref::${REPOSITORYCRD}
       - name: docker login
-        uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
+        uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml
index bb8c9e0..162f564 100644
--- a/.github/workflows/publish-package.yml
+++ b/.github/workflows/publish-package.yml
@@ -36,7 +36,7 @@ jobs:
         run: |
           echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
       - name: docker login
-        uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
+        uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
diff --git a/.github/workflows/publish-sample.yml b/.github/workflows/publish-sample.yml
index 6eaf7db..e7eb67a 100644
--- a/.github/workflows/publish-sample.yml
+++ b/.github/workflows/publish-sample.yml
@@ -23,7 +23,7 @@ jobs:
           echo "REPOSITORY=${{ env.REGISTRY }}/${{ github.repository }}" >> $GITHUB_ENV
 
       - name: Log in to the GHCR
-        uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
+        uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
         with:
           registry: ${{ env.REGISTRY }}
           username: ${{ github.actor }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 2066b02..de5ba7e 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -26,7 +26,7 @@ jobs:
         go-version: '1.21'
 
     - name: Goreleaser
-      uses: goreleaser/goreleaser-action@5742e2a039330cbb23ebf35f046f814d4c6ff811 # v5.1.0
+      uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0
       with:
         version: '1.18.0'
         args: release --rm-dist
diff --git a/.github/workflows/run-full-validation.yml b/.github/workflows/run-full-validation.yml
index 630145e..7f62284 100644
--- a/.github/workflows/run-full-validation.yml
+++ b/.github/workflows/run-full-validation.yml
@@ -4,10 +4,10 @@ on:
   pull_request:
     branches:
       - main
-      - 1.0.0*
+      - release*
   push:
     branches:
-      - 1.0.0*
+      - release*
       - main
   workflow_dispatch:
 
@@ -25,7 +25,7 @@ jobs:
       fail-fast: false
       matrix:
         KUBERNETES_VERSION: ["1.28.7", "1.29.2"]
-        GATEKEEPER_VERSION: ["3.13.0", "3.14.0", "3.15.0"]
+        GATEKEEPER_VERSION: ["3.14.0", "3.15.0", "3.16.0"]
     uses: ./.github/workflows/e2e-k8s.yml 
     with:
       k8s_version: ${{ matrix.KUBERNETES_VERSION }}
@@ -40,7 +40,7 @@ jobs:
       fail-fast: false
       matrix:
         KUBERNETES_VERSION: ["1.27.9", "1.29.2"]
-        GATEKEEPER_VERSION: ["3.13.0", "3.14.0", "3.15.0"]
+        GATEKEEPER_VERSION: ["3.14.0", "3.15.0", "3.16.0"]
     uses: ./.github/workflows/e2e-aks.yml
     with:
       k8s_version: ${{ matrix.KUBERNETES_VERSION }}
@@ -67,7 +67,7 @@ jobs:
           go-version: '1.21'
 
       - name: Az CLI login
-        uses: azure/login@6b2456866fc08b011acb422a92a4aa20e2c4de32 # v2.1.0
+        uses: azure/login@6c251865b4e6290e7b78be643ea2d005bc51f69a # v2.1.1
         with:
           client-id: ${{ env.AZURE_CLIENT_ID }}
           tenant-id: ${{ env.AZURE_TENANT_ID }}
diff --git a/.github/workflows/scan-vulns.yaml b/.github/workflows/scan-vulns.yaml
new file mode 100644
index 0000000..956bf6f
--- /dev/null
+++ b/.github/workflows/scan-vulns.yaml
@@ -0,0 +1,73 @@
+name: scan_vulns
+on:
+  push:
+    paths-ignore:
+      - "docs/**"
+      - "library/**"
+      - "**.md"
+  pull_request:
+    paths-ignore:
+      - "docs/**"
+      - "library/**"
+      - "**.md"
+  workflow_dispatch:
+
+permissions: read-all
+
+jobs:
+  govulncheck:
+    name: "Run govulncheck"
+    runs-on: ubuntu-22.04
+    timeout-minutes: 15
+    steps:
+      - name: Harden Runner
+        uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
+        with:
+          egress-policy: audit
+
+      - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
+        with:
+          go-version: "1.22"
+          check-latest: true
+      - uses: golang/govulncheck-action@dd0578b371c987f96d1185abb54344b44352bd58 # v1.0.3
+
+  scan_vulnerabilities:
+    name: "[Trivy] Scan for vulnerabilities"
+    runs-on: ubuntu-22.04
+    timeout-minutes: 15
+    steps:
+      - name: Harden Runner
+        uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
+        with:
+          egress-policy: audit
+
+      - name: Check out code into the Go module directory
+        uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
+
+      - name: Download trivy
+        run: |
+          pushd $(mktemp -d)
+          wget https://github.com/aquasecurity/trivy/releases/download/v${{ env.TRIVY_VERSION }}/trivy_${{ env.TRIVY_VERSION }}_Linux-64bit.tar.gz
+          tar zxvf trivy_${{ env.TRIVY_VERSION }}_Linux-64bit.tar.gz
+          echo "$(pwd)" >> $GITHUB_PATH
+        env:
+          TRIVY_VERSION: "0.46.0"
+
+      - name: Run trivy on git repository
+        run: |
+          trivy fs --format table --ignore-unfixed --scanners vuln .
+
+      - name: Build docker images
+        run: |
+          make e2e-build-local-ratify-image
+          make e2e-build-crd-image
+      - name: Run trivy on images for all severity
+        run: |
+          for img in "localbuild:test" "localbuildcrd:test"; do
+              trivy image --ignore-unfixed --vuln-type="os,library" "${img}"
+          done
+      - name: Run trivy on images and exit on HIGH severity
+        run: |
+          for img in "localbuild:test" "localbuildcrd:test"; do
+              trivy image --ignore-unfixed --exit-code 1 --severity HIGH --vuln-type="os,library" "${img}"
+          done
\ No newline at end of file
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index 2c4f6cb..a0f9f0d 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -8,6 +8,10 @@ on:
     branches:
       - main
       - dev
+  pull_request:
+    branches:
+      - dev
+      - main
   workflow_dispatch:
 
 permissions: read-all
@@ -44,6 +48,6 @@ jobs:
           retention-days: 5
       
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@9fdb3e49720b44c48891d036bb502feb25684276 # tag=v3.25.6
+        uses: github/codeql-action/upload-sarif@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # tag=v3.25.8
         with:
           sarif_file: results.sarif
diff --git a/Makefile b/Makefile
index 6e9f841..3801ecd 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,7 @@ LDFLAGS += -X $(GO_PKG)/internal/version.GitTag=$(GIT_TAG)
 KIND_VERSION ?= 0.22.0
 KUBERNETES_VERSION ?= 1.29.2
 KIND_KUBERNETES_VERSION ?= 1.29.2
-GATEKEEPER_VERSION ?= 3.15.0
+GATEKEEPER_VERSION ?= 3.16.0
 DAPR_VERSION ?= 1.12.5
 COSIGN_VERSION ?= 2.2.3
 NOTATION_VERSION ?= 1.1.0
@@ -65,6 +65,7 @@ TEST_REGISTRY_PASSWORD = test_pw
 # Azure Key Vault Setup
 KEYVAULT_NAME ?= ratify-akv
 KEYVAULT_KEY_NAME ?= test-key
+AZURE_SP_OBJECT_ID ?= 00000000-0000-0000-0000-000000000000
 
 all: build test
 
@@ -518,44 +519,45 @@ e2e-azure-setup: e2e-create-all-image e2e-notation-setup e2e-notation-leaf-cert-
 
 e2e-deploy-gatekeeper: e2e-helm-install
 	./.staging/helm/linux-amd64/helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
-	if [ ${GATEKEEPER_VERSION} = "3.13.0" ]; then ./.staging/helm/linux-amd64/helm install gatekeeper/gatekeeper --version ${GATEKEEPER_VERSION} --name-template=gatekeeper --namespace ${GATEKEEPER_NAMESPACE} --create-namespace --set enableExternalData=true --set validatingWebhookTimeoutSeconds=5 --set mutatingWebhookTimeoutSeconds=2 --set auditInterval=0; fi
-	if [ ${GATEKEEPER_VERSION} = "3.13.0" ]; then kubectl -n ${GATEKEEPER_NAMESPACE} patch deployment gatekeeper-controller-manager --type=json -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--external-data-provider-response-cache-ttl=1s"}]' && sleep 60; fi
-	# Gatekeeper versions >= 3.14.0 need a special helm value to override the default external data response cache ttl to 10s
-	if [ ${GATEKEEPER_VERSION} != "3.13.0" ]; then ./.staging/helm/linux-amd64/helm install gatekeeper/gatekeeper --version ${GATEKEEPER_VERSION} --name-template=gatekeeper --namespace ${GATEKEEPER_NAMESPACE} --create-namespace --set enableExternalData=true --set validatingWebhookTimeoutSeconds=5 --set mutatingWebhookTimeoutSeconds=2 --set auditInterval=0 --set externaldataProviderResponseCacheTTL=1s; fi
+	./.staging/helm/linux-amd64/helm install gatekeeper/gatekeeper --version ${GATEKEEPER_VERSION} --name-template=gatekeeper --namespace ${GATEKEEPER_NAMESPACE} --create-namespace --set enableExternalData=true --set validatingWebhookTimeoutSeconds=5 --set mutatingWebhookTimeoutSeconds=2 --set auditInterval=0 --set externaldataProviderResponseCacheTTL=1s
 
 e2e-build-crd-image:
-	docker build --progress=plain --no-cache --build-arg KUBE_VERSION=${KUBERNETES_VERSION} --build-arg TARGETOS="linux" --build-arg TARGETARCH="amd64" -f crd.Dockerfile -t localbuildcrd:test ./charts/ratify/crds
-	kind load docker-image --name kind localbuildcrd:test
+	docker build --progress=plain --no-cache --build-arg KUBE_VERSION=${KUBERNETES_VERSION} --build-arg TARGETOS="linux" --build-arg TARGETARCH="amd64" -f crd.Dockerfile -t localbuildcrd:test ./charts/ratify/crds	
 
-e2e-deploy-base-ratify: e2e-notation-setup e2e-notation-leaf-cert-setup e2e-inlinecert-setup e2e-build-crd-image
-	docker build --progress=plain --no-cache \
-	-f ./httpserver/Dockerfile \
-	-t baselocalbuild:test .
-	kind load docker-image --name kind baselocalbuild:test
+load-build-crd-image:
+	kind load docker-image --name kind localbuildcrd:test
 
+e2e-deploy-base-ratify: e2e-notation-setup e2e-notation-leaf-cert-setup e2e-cosign-setup e2e-inlinecert-setup e2e-build-crd-image load-build-crd-image e2e-build-local-ratify-base-image
 	printf "{\n\t\"auths\": {\n\t\t\"registry:5000\": {\n\t\t\t\"auth\": \"`echo "${TEST_REGISTRY_USERNAME}:${TEST_REGISTRY_PASSWORD}" | tr -d '\n' | base64 -i -w 0`\"\n\t\t}\n\t}\n}" > mount_config.json
 
 	./.staging/helm/linux-amd64/helm install ${RATIFY_NAME} \
-    ./charts/ratify --atomic --namespace ${GATEKEEPER_NAMESPACE} --create-namespace \
-	--set image.repository=baselocalbuild \
-	--set image.crdRepository=localbuildcrd \
-	--set image.tag=test \
-	--set gatekeeper.version=${GATEKEEPER_VERSION} \
-	--set featureFlags.RATIFY_CERT_ROTATION=${CERT_ROTATION_ENABLED} \
-	--set-file provider.tls.crt=${CERT_DIR}/server.crt \
-	--set-file provider.tls.key=${CERT_DIR}/server.key \
-	--set-file provider.tls.caCert=${CERT_DIR}/ca.crt \
-    --set-file provider.tls.caKey=${CERT_DIR}/ca.key \
-	--set provider.tls.cabundle="$(shell cat ${CERT_DIR}/ca.crt | base64 | tr -d '\n')" \
-	--set notationCerts[0]="$$(cat ~/.config/notation/localkeys/ratify-bats-test.crt)" \
-	--set oras.useHttp=true \
-	--set cosign.enabled=false \
-	--set-file dockerConfig="mount_config.json" \
-	--set logger.level=debug
+		./charts/ratify --atomic --namespace ${GATEKEEPER_NAMESPACE} --create-namespace \
+		--set image.repository=baselocalbuild \
+		--set image.crdRepository=localbuildcrd \
+		--set image.tag=test \
+		--set gatekeeper.version=${GATEKEEPER_VERSION} \
+		--set featureFlags.RATIFY_CERT_ROTATION=${CERT_ROTATION_ENABLED} \
+		--set-file provider.tls.crt=${CERT_DIR}/server.crt \
+		--set-file provider.tls.key=${CERT_DIR}/server.key \
+		--set-file provider.tls.caCert=${CERT_DIR}/ca.crt \
+		--set-file provider.tls.caKey=${CERT_DIR}/ca.key \
+		--set provider.tls.cabundle="$(shell cat ${CERT_DIR}/ca.crt | base64 | tr -d '\n')" \
+		--set notationCerts[0]="$$(cat ~/.config/notation/localkeys/ratify-bats-test.crt)" \
+		--set cosignKeys[0]="$$(cat .staging/cosign/cosign.pub)" \
+		--set cosign.key="$$(cat .staging/cosign/cosign.pub)" \
+		--set oras.useHttp=true \
+		--set-file dockerConfig="mount_config.json" \
+		--set logger.level=debug
 
 	rm mount_config.json
 
-e2e-deploy-ratify: e2e-notation-setup e2e-notation-leaf-cert-setup e2e-cosign-setup e2e-cosign-setup e2e-licensechecker-setup e2e-sbom-setup e2e-schemavalidator-setup e2e-vulnerabilityreport-setup e2e-inlinecert-setup e2e-build-crd-image e2e-build-local-ratify-image e2e-helm-deploy-ratify
+e2e-deploy-ratify: e2e-notation-setup e2e-notation-leaf-cert-setup e2e-cosign-setup e2e-cosign-setup e2e-licensechecker-setup e2e-sbom-setup e2e-schemavalidator-setup e2e-vulnerabilityreport-setup e2e-inlinecert-setup e2e-build-crd-image load-build-crd-image e2e-build-local-ratify-image load-local-ratify-image e2e-helm-deploy-ratify
+
+e2e-build-local-ratify-base-image:
+	docker build --progress=plain --no-cache \
+		-f ./httpserver/Dockerfile \
+		-t baselocalbuild:test .
+	kind load docker-image --name kind baselocalbuild:test
 
 e2e-build-local-ratify-image:
 	docker build --progress=plain --no-cache \
@@ -565,6 +567,8 @@ e2e-build-local-ratify-image:
 	--build-arg build_vulnerabilityreport=true \
 	-f ./httpserver/Dockerfile \
 	-t localbuild:test .
+
+load-local-ratify-image:
 	kind load docker-image --name kind localbuild:test
 
 e2e-helmfile-deploy-released-ratify:
@@ -588,6 +592,7 @@ e2e-helm-deploy-ratify:
 	--set notationCerts[0]="$$(cat ~/.config/notation/localkeys/ratify-bats-test.crt)" \
 	--set cosignKeys[0]="$$(cat .staging/cosign/cosign.pub)" \
 	--set cosign.key="$$(cat .staging/cosign/cosign.pub)" \
+	--set cosign.tLogVerify=false \
 	--set oras.useHttp=true \
 	--set-file dockerConfig="mount_config.json" \
 	--set logger.level=debug
@@ -607,6 +612,7 @@ e2e-helm-deploy-ratify-without-tls-certs:
 	--set notaryCert="$$(cat ~/.config/notation/localkeys/ratify-bats-test.crt)" \
 	--set cosign.key="$$(cat .staging/cosign/cosign.pub)" \
 	--set cosignKeys[0]="$$(cat .staging/cosign/cosign.pub)" \
+	--set cosign.tLogVerify=false \
 	--set oras.useHttp=true \
 	--set-file dockerConfig="mount_config.json" \
 	--set logger.level=debug
@@ -630,7 +636,7 @@ e2e-helm-deploy-redis: e2e-helm-deploy-dapr
 	kubectl apply -f test/testdata/dapr/dapr-redis-secret.yaml -n ${GATEKEEPER_NAMESPACE}
 	kubectl apply -f test/testdata/dapr/dapr-redis.yaml -n ${GATEKEEPER_NAMESPACE}
  
-e2e-helm-deploy-ratify-replica: e2e-helm-deploy-redis e2e-notation-setup e2e-build-crd-image e2e-build-local-ratify-image
+e2e-helm-deploy-ratify-replica: e2e-helm-deploy-redis e2e-notation-setup e2e-build-crd-image load-build-crd-image e2e-build-local-ratify-image load-local-ratify-image
 	printf "{\n\t\"auths\": {\n\t\t\"registry:5000\": {\n\t\t\t\"auth\": \"`echo "${TEST_REGISTRY_USERNAME}:${TEST_REGISTRY_PASSWORD}" | tr -d '\n' | base64 -i -w 0`\"\n\t\t}\n\t}\n}" > mount_config.json
 
 	./.staging/helm/linux-amd64/helm install ${RATIFY_NAME} \
@@ -660,7 +666,7 @@ e2e-helm-deploy-ratify-replica: e2e-helm-deploy-redis e2e-notation-setup e2e-bui
 	rm mount_config.json
 
 e2e-aks:
-	./scripts/azure-ci-test.sh ${KUBERNETES_VERSION} ${GATEKEEPER_VERSION} ${TENANT_ID} ${GATEKEEPER_NAMESPACE} ${CERT_DIR}
+	./scripts/azure-ci-test.sh ${KUBERNETES_VERSION} ${GATEKEEPER_VERSION} ${TENANT_ID} ${GATEKEEPER_NAMESPACE} ${CERT_DIR} ${AZURE_SP_OBJECT_ID}
 
 e2e-cleanup:
 	./scripts/azure-ci-test-cleanup.sh ${AZURE_SUBSCRIPTION_ID}
diff --git a/ROADMAP.md b/ROADMAP.md
index 5ae2a03..9b444c8 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -44,27 +44,29 @@ The Ratify roadmap is divided into milestones, each with a set of features (high
 
 ### v1.2
 
-**Status**: In progress
+**Status**: Completed
+
+**Target date**: May 31, 2024
 
-**Target date**: Apr 30, 2024
+**Release link**: [v1.2.0 Release Notes](https://github.com/deislabs/ratify/releases/tag/v1.2.0)
 
 **major features**
 
 - Kubernetes multi-tenancy support (Namespace-specific policies)
 - OCI v1.1 compliance
 - Cosign signatures verification using keys in AKV
-- Error logs improvements
 
 See details in [GitHub milestone v1.2.0](https://github.com/deislabs/ratify/issues?q=is%3Aopen+is%3Aissue+milestone%3Av1.2.0).
 
 ### v1.3
 
-**Status**: Not started
+**Status**: In progress
 
-**Target date**: Jun 30, 2024
+**Target date**: Aug 30, 2024
 
 **Major features**
 
+- Error logs improvements
 - Kubernetes multi-tenancy support (Verifying Common images across namespaces)
 - Cosign keyless verification using OIDC settings
 - Notary Project signature verification with Time-stamping support
@@ -76,11 +78,12 @@ See details in [GitHub milestone v1.3.0](https://github.com/deislabs/ratify/issu
 
 **Status**: Tentative
 
-**Target date**: Sep 30, 2024
+**Target date**: Nov 30, 2024
 
 **Major features**
 
 - Attestations support
+- Ratify supports Azure Trusted Signing as a new KeyManagementProvider
 - Use Ratify at container runtime (Preview)
 
 ### v2.0
diff --git a/archive/meeting-notes/ratify-weekly-notes-2023-Jan-2023-Jun.md b/archive/meeting-notes/ratify-weekly-notes-2023-Jan-2023-Jun.md
index b328afc..c70e59c 100644
--- a/archive/meeting-notes/ratify-weekly-notes-2023-Jan-2023-Jun.md
+++ b/archive/meeting-notes/ratify-weekly-notes-2023-Jan-2023-Jun.md
@@ -785,7 +785,7 @@ Recording: https://youtu.be/vn_GOUXZGhw
 
 ### Presentation/Discussion Agenda Items:
 - [Akash]How do we handle breaking changes that require a change to the README? (Akash) From last week   
-   [Susan] Maybe link to github page something like https://deislabs.github.io/ratify/getting-started.html? how does csi driver maintain its docs ? https://secrets-store-csi-driver.sigs.k8s.io/getting-started/getting-started.html
+   [Susan] Maybe link to github page something like https://ratify-project.github.io/ratify/getting-started.html? how does csi driver maintain its docs ? https://secrets-store-csi-driver.sigs.k8s.io/getting-started/getting-started.html
    [Sajay] Not sure if external doc will have maintainance overhead. We can add a link to the quickstart that is pinned to a released version for now.
    
 - [Akash] Cosign auth support: https://hackmd.io/@akashsinghal/rks7vlOps
diff --git a/charts/ratify/Chart.yaml b/charts/ratify/Chart.yaml
index 173ba0f..57fba1d 100644
--- a/charts/ratify/Chart.yaml
+++ b/charts/ratify/Chart.yaml
@@ -1,7 +1,7 @@
 apiVersion: v2
 name: ratify
 description: A Helm chart for Ratify
-version: 1.12.0
-appVersion: v1.1.0
+version: 1.13.0
+appVersion: v1.2.0
 home: https://github.com/deislabs/ratify
 icon: https://raw.githubusercontent.com/deislabs/ratify/main/logo.svg
diff --git a/charts/ratify/README.md b/charts/ratify/README.md
index 4ec94ee..862ae8c 100644
--- a/charts/ratify/README.md
+++ b/charts/ratify/README.md
@@ -3,7 +3,7 @@
 ## Get Repo Info
 
 ```console
-helm repo add ratify https://deislabs.github.io/ratify
+helm repo add ratify https://ratify-project.github.io/ratify
 helm repo update
 ```
 
@@ -51,6 +51,13 @@ Values marked `# DEPRECATED` in the `values.yaml` as well as **DEPRECATED** in t
 | cosignKeys                                         | An array of public keys used to create inline key management providers used by Cosign verifier                                                                                                                                                                                                                                                                         | `[]`                              |
 | cosign.enabled                                     | Enables/disables cosign tag-based signature lookup in ORAS store. MUST be set to true for cosign verification.                                                                                                                                                                                                                                                         | `true`                            |
 | cosign.scopes                                      | An array of scopes relevant to the single trust policy configured in Cosign verifier. A scope of '*' is a global wildcard character to represent all images apply.                                                                                                                                                                                                     | `["*"]`                           |
+| cosign.rekorURL                                    | URL string reference to remote rekor server. If not specified, implementation will default to use Rekor public good instance `https://rekor.sigstore.dev`.                                                                                                                                                                                                             | ``                                |
+| cosign.tLogVerify                                  | Enables/disables verification of presence of signature in Transparency log.                                                                                                                                                                                                                                                                                            | `true`                            |
+| cosign.keyless.ctLogVerify                         | Enables/disables verification of presence of Secure Certificate Timestamp (SCT) in transparency log                                                                                                                                                                                                                                                                    | `true`                            |
+| cosign.keyless.certificateIdentity                 | String certificate identity used for exact identity match during verification. Either `certificateIdentity` or `certificateIdentityRegExp` MUST be defined, but both cannot be defined at together                                                                                                                                                                        | ``                                |
+| cosign.keyless.certificateIdentityRegExp              | String certificate identity regular expression for identity matching during verification. Accepts the Go regular expression syntax described at https://golang.org/s/re2syntax. Either `certificateIdentity` or `certificateIdentityRegExp` MUST be defined, but both cannot be defined together                                                                          | ``                                |
+| cosign.keyless.certificateOIDCIssuer               | String certificate OIDC issuer for exact issuer matching during verification. Either `certificateOIDCIssuer` or `certificateOIDCIssuerRegExp` MUST be defined, but both cannot be defined together                                                                                                                                                                        | ``                                |
+| cosign.keyless.certificateOIDCIssuerRegExp            | String certificate OIDC issuer regular expression for issuer matching during verification. Accepts the Go regular expression syntax described at https://golang.org/s/re2syntax. Either `certificateOIDCIssuer` or `certificateOIDCIssuerRegExp` MUST be defined, but both cannot be defined together                                                                     | ``                                |
 | vulnerabilityreport.enabled                        | Enables/disables installation of vulnerability report verifier                                                                                                                                                                                                                                                                                                         | `false`                           |
 | vulnerabilityreport.passthrough                    | Enables/disables passthrough. All validation except `maximumAge` are disregarded and report content is added to verifier report                                                                                                                                                                                                                                        | `false`                           |
 | vulnerabilityreport.schemaURL                      | URL for JSON schema to validate report against                                                                                                                                                                                                                                                                                                                         | ``                                |
@@ -69,7 +76,7 @@ Values marked `# DEPRECATED` in the `values.yaml` as well as **DEPRECATED** in t
 | resources.requests.memory                          | Memory request of Ratify Deployment                                                                                                                                                                                                                                                                                                                                    | `512Mi`                           |
 | serviceAccount.create                              | Create new dedicated Ratify service account                                                                                                                                                                                                                                                                                                                            | `true`                            |
 | serviceAccount.name                                | Name of Ratify service account to create                                                                                                                                                                                                                                                                                                                               | `ratify-admin`                    |
-| gatekeeper.version                                 | Determines the Gatekeeper CRD versioning                                                                                                                                                                                                                                                                                                                               | `3.15.0`                          |
+| gatekeeper.version                                 | Determines the Gatekeeper CRD versioning                                                                                                                                                                                                                                                                                                                               | `3.16.0`                          |
 | gatekeeper.namespace                               | Namespace Gatekeeper is installed                                                                                                                                                                                                                                                                                                                                      | `gatekeeper-system`               |
 | instrumentation.metricsEnabled                     | Initializes the configured metrics provider                                                                                                                                                                                                                                                                                                                            | `true`                            |
 | instrumentation.metricsType                        | Specifies the metrics provider type                                                                                                                                                                                                                                                                                                                                    | `prometheus`                      |
diff --git a/charts/ratify/templates/_helpers.tpl b/charts/ratify/templates/_helpers.tpl
index e57008c..cc56acb 100644
--- a/charts/ratify/templates/_helpers.tpl
+++ b/charts/ratify/templates/_helpers.tpl
@@ -146,4 +146,20 @@ Set the namespace exclusions for Assign
 {{- if and (ne .Release.Namespace $gkNamespace) (ne .Release.Namespace "kube-system") }}
 - {{ .Release.Namespace | quote}}
 {{- end }}
+{{- end }}
+
+{{/*
+Choose cosign legacy or not. Determined by if cosignKeys are provided or not
+OR if azurekeyvault is enabled and keys are provided
+OR if keyless is enabled and certificateIdentity, certificateIdentityRegExp, certificateOIDCIssuer, or certificateOIDCIssuerExp are provided
+*/}}
+{{- define "ratify.cosignLegacy" -}}
+{{- $cosignKeysPresent := gt (len .Values.cosignKeys) 0 -}}
+{{- $azureKeyVaultEnabled := .Values.azurekeyvault.enabled -}}
+{{- $azureKeyVaultKeysPresent := gt (len .Values.azurekeyvault.keys) 0 -}}
+{{- if or $cosignKeysPresent (and $azureKeyVaultEnabled $azureKeyVaultKeysPresent) .Values.cosign.keyless.certificateIdentity .Values.cosign.keyless.certificateIdentityRegExp .Values.cosign.keyless.certificateOIDCIssuer .Values.cosign.keyless.certificateOIDCIssuerExp -}}
+false
+{{- else }}
+true
+{{- end }}
 {{- end }}
\ No newline at end of file
diff --git a/charts/ratify/templates/verifier.yaml b/charts/ratify/templates/verifier.yaml
index 367b7a1..2c7556a 100644
--- a/charts/ratify/templates/verifier.yaml
+++ b/charts/ratify/templates/verifier.yaml
@@ -50,7 +50,7 @@ spec:
   name: cosign
   artifactTypes: application/vnd.dev.cosign.artifact.sig.v1+json
   parameters:
-    {{- if or (gt (len .Values.cosignKeys) 0) (and .Values.azurekeyvault.enabled (gt (len .Values.azurekeyvault.keys) 0)) }}
+    {{- if  (eq (include "ratify.cosignLegacy" .) "false") }}
     trustPolicies:
       - name: default
         version: 1.0.0
@@ -65,6 +65,16 @@ spec:
           {{- if and .Values.azurekeyvault.enabled (gt (len .Values.azurekeyvault.keys) 0) }}
           - provider: kmprovider-akv
           {{- end }}
+        tLogVerify: {{ .Values.cosign.tLogVerify }}
+        rekorURL: {{ .Values.cosign.rekorURL }}
+        {{- if or .Values.cosign.keyless.certificateIdentity .Values.cosign.keyless.certificateIdentityRegExp .Values.cosign.keyless.certificateOIDCIssuer .Values.cosign.keyless.certificateOIDCIssuerRegExp }}
+        keyless:
+          ctLogVerify: {{ .Values.cosign.keyless.ctLogVerify }}
+          certificateIdentity: {{ .Values.cosign.keyless.certificateIdentity }}
+          certificateIdentityRegExp: {{ .Values.cosign.keyless.certificateIdentityRegExp }}
+          certificateOIDCIssuer: {{ .Values.cosign.keyless.certificateOIDCIssuer }}
+          certificateOIDCIssuerRegExp: {{ .Values.cosign.keyless.certificateOIDCIssuerRegExp }}
+        {{- end }}
     {{- else }}
     key: /usr/local/ratify-certs/cosign/cosign.pub
     {{- end }}
diff --git a/charts/ratify/values.yaml b/charts/ratify/values.yaml
index f25a58b..b1ad2ef 100644
--- a/charts/ratify/values.yaml
+++ b/charts/ratify/values.yaml
@@ -1,7 +1,7 @@
 image:
   repository: ghcr.io/deislabs/ratify
   crdRepository: ghcr.io/deislabs/ratify-crds
-  tag: v1.1.0
+  tag: v1.2.0
   pullPolicy: IfNotPresent
 
 nameOverride: ""
@@ -16,6 +16,15 @@ cosign:
   enabled: true
   scopes: ["*"] # corresponds to a single trust policy
   key: "" # DEPRECATED: Use cosignKeys instead
+  rekorURL: ""
+  tLogVerify: true
+  keyless:
+    ctLogVerify: true
+    certificateIdentity: ""
+    certificateIdentityRegExp: ""
+    certificateOIDCIssuer: ""
+    certificateOIDCIssuerRegExp: ""
+
 vulnerabilityreport:
   enabled: false
   passthrough: false
@@ -41,7 +50,7 @@ serviceAccount:
   create: true
   name: ratify-admin
 gatekeeper:
-  version: "3.15.0"
+  version: "3.16.0"
   namespace: # default is gatekeeper-system
 instrumentation:
   metricsEnabled: true
diff --git a/config/samples/clustered/verifier/config_v1beta1_verifier_cosign.yaml b/config/samples/clustered/verifier/config_v1beta1_verifier_cosign.yaml
index 713f571..89719fe 100644
--- a/config/samples/clustered/verifier/config_v1beta1_verifier_cosign.yaml
+++ b/config/samples/clustered/verifier/config_v1beta1_verifier_cosign.yaml
@@ -11,4 +11,5 @@ spec:
         scopes:
           - "*"
         keys:
-          - provider: ratify-cosign-inline-key-0
\ No newline at end of file
+          - provider: ratify-cosign-inline-key-0
+        tLogVerify: false
\ No newline at end of file
diff --git a/config/samples/clustered/verifier/config_v1beta1_verifier_cosign_keyless.yaml b/config/samples/clustered/verifier/config_v1beta1_verifier_cosign_keyless_legacy.yaml
similarity index 100%
rename from config/samples/clustered/verifier/config_v1beta1_verifier_cosign_keyless.yaml
rename to config/samples/clustered/verifier/config_v1beta1_verifier_cosign_keyless_legacy.yaml
diff --git a/config/samples/namespaced/verifier/config_v1beta1_verifier_cosign.yaml b/config/samples/namespaced/verifier/config_v1beta1_verifier_cosign.yaml
index dfb4597..44b4bda 100644
--- a/config/samples/namespaced/verifier/config_v1beta1_verifier_cosign.yaml
+++ b/config/samples/namespaced/verifier/config_v1beta1_verifier_cosign.yaml
@@ -12,3 +12,4 @@ spec:
           - "*"
         keys:
           - provider: default/ratify-cosign-inline-key-0
+        tLogVerify: false
diff --git a/crd.Dockerfile b/crd.Dockerfile
index 45067fc..68dc59b 100644
--- a/crd.Dockerfile
+++ b/crd.Dockerfile
@@ -11,7 +11,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
       
-FROM alpine@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b as builder
+FROM alpine@sha256:77726ef6b57ddf65bb551896826ec38bc3e53f75cdde31354fbffb4f25238ebd as builder
 
 ARG TARGETOS
 ARG TARGETARCH
diff --git a/dev.helmfile.yaml b/dev.helmfile.yaml
index 51ae171..ac8f79d 100644
--- a/dev.helmfile.yaml
+++ b/dev.helmfile.yaml
@@ -2,15 +2,15 @@ repositories:
   - name: gatekeeper
     url: https://open-policy-agent.github.io/gatekeeper/charts
   - name: ratify
-    url: ghcr.io/deislabs/ratify-chart-dev # PRERELEASE: Change to 'https://deislabs.github.io/ratify' before copying to helmfile.yaml
+    url: ghcr.io/deislabs/ratify-chart-dev # PRERELEASE: Change to 'https://ratify-project.github.io/ratify' before copying to helmfile.yaml
     oci: true # PRERELEASE: Remove before copying to helmfile.yaml
-    
+
 releases:
   - name: gatekeeper
     namespace: gatekeeper-system
     createNamespace: true
     chart: gatekeeper/gatekeeper
-    version: 3.15.0
+    version: 3.16.0
     wait: true
     set:
       - name: enableExternalData
@@ -34,14 +34,14 @@ releases:
         command: "bash"
         args:
           - "-c"
-          - "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"
+          - "kubectl apply -f https://ratify-project.github.io/ratify/library/default/template.yaml && kubectl apply -f https://ratify-project.github.io/ratify/library/default/samples/constraint.yaml"
       - events: ["postuninstall"]
         showlogs: true
         command: "kubectl"
         args:
           - "delete"
           - "-f"
-          - "https://deislabs.github.io/ratify/library/default/template.yaml"
+          - "https://ratify-project.github.io/ratify/library/default/template.yaml"
           - "--ignore-not-found=true"
       - events: ["postuninstall"]
         showlogs: true
@@ -49,7 +49,7 @@ releases:
         args:
           - "delete"
           - "-f"
-          - "https://deislabs.github.io/ratify/library/default/samples/constraint.yaml"
+          - "https://ratify-project.github.io/ratify/library/default/samples/constraint.yaml"
           - "--ignore-not-found=true"
       - events: ["postuninstall"]
         showlogs: true
diff --git a/dev.high-availability.helmfile.yaml b/dev.high-availability.helmfile.yaml
index c7b6e7a..20f1fd4 100644
--- a/dev.high-availability.helmfile.yaml
+++ b/dev.high-availability.helmfile.yaml
@@ -6,9 +6,9 @@ repositories:
   - name: bitnami
     url: https://charts.bitnami.com/bitnami
   - name: ratify
-    url: ghcr.io/deislabs/ratify-chart-dev # PRERELEASE: Change to 'https://deislabs.github.io/ratify' before copying to helmfile.yaml
+    url: ghcr.io/deislabs/ratify-chart-dev # PRERELEASE: Change to 'https://ratify-project.github.io/ratify' before copying to helmfile.yaml
     oci: true # PRERELEASE: Remove before copying to helmfile.yaml
-    
+
 releases:
   - name: dapr
     namespace: dapr-system
@@ -20,7 +20,7 @@ releases:
     namespace: gatekeeper-system
     createNamespace: true
     chart: gatekeeper/gatekeeper
-    version: 3.15.0
+    version: 3.16.0
     wait: true
     set:
       - name: enableExternalData
@@ -78,7 +78,7 @@ releases:
         command: "bash"
         args:
           - "-c"
-          - "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"
+          - "kubectl apply -f https://ratify-project.github.io/ratify/library/default/template.yaml && kubectl apply -f https://ratify-project.github.io/ratify/library/default/samples/constraint.yaml"
       - events: ["postuninstall"]
         showlogs: true
         command: "kubectl"
@@ -105,7 +105,7 @@ releases:
         args:
           - "delete"
           - "-f"
-          - "https://deislabs.github.io/ratify/library/default/template.yaml"
+          - "https://ratify-project.github.io/ratify/library/default/template.yaml"
           - "--ignore-not-found=true"
       - events: ["postuninstall"]
         showlogs: true
@@ -113,7 +113,7 @@ releases:
         args:
           - "delete"
           - "-f"
-          - "https://deislabs.github.io/ratify/library/default/samples/constraint.yaml"
+          - "https://ratify-project.github.io/ratify/library/default/samples/constraint.yaml"
           - "--ignore-not-found=true"
       - events: ["postuninstall"]
         showlogs: true
diff --git a/go.mod b/go.mod
index 656b820..b6d233e 100644
--- a/go.mod
+++ b/go.mod
@@ -14,9 +14,9 @@ require (
 	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2
 	github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2
 	github.com/aws/aws-sdk-go-v2 v1.27.0
-	github.com/aws/aws-sdk-go-v2/config v1.27.15
-	github.com/aws/aws-sdk-go-v2/credentials v1.17.15
-	github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2
+	github.com/aws/aws-sdk-go-v2/config v1.27.16
+	github.com/aws/aws-sdk-go-v2/credentials v1.17.16
+	github.com/aws/aws-sdk-go-v2/service/ecr v1.28.3
 	github.com/cespare/xxhash/v2 v2.2.0
 	github.com/dapr/go-sdk v1.8.0
 	github.com/dgraph-io/ristretto v0.1.1
@@ -28,7 +28,7 @@ require (
 	github.com/golang/protobuf v1.5.4
 	github.com/google/go-containerregistry v0.19.1
 	github.com/gorilla/mux v1.8.1
-	github.com/notaryproject/notation-core-go v1.0.2
+	github.com/notaryproject/notation-core-go v1.0.3
 	github.com/notaryproject/notation-go v1.0.1
 	github.com/open-policy-agent/cert-controller v0.8.0
 	github.com/open-policy-agent/frameworks/constraint v0.0.0-20230411224310-3f237e2710fa
@@ -38,7 +38,7 @@ require (
 	github.com/owenrumney/go-sarif/v2 v2.3.1
 	github.com/pkg/errors v0.9.1
 	github.com/sigstore/cosign/v2 v2.2.4
-	github.com/sigstore/sigstore v1.8.3
+	github.com/sigstore/sigstore v1.8.4
 	github.com/sirupsen/logrus v1.9.3
 	github.com/spdx/tools-golang v0.5.4
 	github.com/spf13/cobra v1.8.0
@@ -56,7 +56,7 @@ require (
 )
 
 require (
-	cloud.google.com/go/compute/metadata v0.2.3 // indirect
+	cloud.google.com/go/compute/metadata v0.3.0 // indirect
 	filippo.io/edwards25519 v1.1.0 // indirect
 	github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 // indirect
 	github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect
@@ -79,8 +79,9 @@ require (
 	github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
 	github.com/aliyun/credentials-go v1.3.1 // indirect
 	github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
-	github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.7 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect
+	github.com/aws/aws-sdk-go-v2/service/kms v1.31.3 // indirect
 	github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 // indirect
 	github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect
 	github.com/clbanning/mxj/v2 v2.7.0 // indirect
@@ -127,11 +128,10 @@ require (
 )
 
 require (
-	cloud.google.com/go/compute v1.25.0 // indirect
 	github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
 	github.com/Azure/go-autorest v14.2.0+incompatible // indirect
 	github.com/Azure/go-autorest/autorest v0.11.29
-	github.com/Azure/go-autorest/autorest/adal v0.9.23
+	github.com/Azure/go-autorest/autorest/adal v0.9.24
 	github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
 	github.com/Azure/go-autorest/logger v0.2.1 // indirect
 	github.com/Azure/go-autorest/tracing v0.6.0 // indirect
@@ -142,9 +142,9 @@ require (
 	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7 // indirect
 	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9 // indirect
-	github.com/aws/aws-sdk-go-v2/service/sso v1.20.8 // indirect
-	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.2 // indirect
-	github.com/aws/aws-sdk-go-v2/service/sts v1.28.9 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sso v1.20.9 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sts v1.28.10 // indirect
 	github.com/aws/smithy-go v1.20.2 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/blang/semver v3.5.1+incompatible // indirect
@@ -155,9 +155,9 @@ require (
 	github.com/docker/docker v24.0.9+incompatible // indirect
 	github.com/docker/docker-credential-helpers v0.8.0 // indirect
 	github.com/dustin/go-humanize v1.0.1 // indirect
-	github.com/fxamacker/cbor/v2 v2.5.0 // indirect
+	github.com/fxamacker/cbor/v2 v2.6.0 // indirect
 	github.com/go-chi/chi v4.1.2+incompatible // indirect
-	github.com/go-logr/logr v1.4.1
+	github.com/go-logr/logr v1.4.2
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-openapi/analysis v0.23.0 // indirect
 	github.com/go-openapi/errors v0.22.0 // indirect
@@ -233,14 +233,14 @@ require (
 	go.uber.org/atomic v1.11.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	go.uber.org/zap v1.27.0 // indirect
-	golang.org/x/crypto v0.22.0
+	golang.org/x/crypto v0.23.0
 	golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect
 	golang.org/x/mod v0.16.0 // indirect
 	golang.org/x/net v0.23.0 // indirect
-	golang.org/x/oauth2 v0.19.0 // indirect
-	golang.org/x/sys v0.19.0 // indirect
-	golang.org/x/term v0.19.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
+	golang.org/x/oauth2 v0.20.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
+	golang.org/x/term v0.20.0 // indirect
+	golang.org/x/text v0.15.0 // indirect
 	golang.org/x/time v0.5.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
diff --git a/go.sum b/go.sum
index 3355263..cf62d1b 100644
--- a/go.sum
+++ b/go.sum
@@ -20,10 +20,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf
 cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
 cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v1.25.0 h1:H1/4SqSUhjPFE7L5ddzHOfY2bCAvjwNRZPNl6Ni5oYU=
-cloud.google.com/go/compute v1.25.0/go.mod h1:GR7F0ZPZH8EhChlMo9FkLd7eUTwEymjqQagxzilIxIE=
-cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
-cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
+cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
+cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
 cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
@@ -69,8 +67,8 @@ github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/
 github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs=
 github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
 github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk=
-github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8=
-github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c=
+github.com/Azure/go-autorest/autorest/adal v0.9.24 h1:BHZfgGsGwdkHDyZdtQRQk1WeUdW0m2WPAwuHZwUi5i4=
+github.com/Azure/go-autorest/autorest/adal v0.9.24/go.mod h1:7T1+g0PYFmACYW5LlG2fcoPiPlFHjClyRGL7dRlP5c8=
 github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk=
 github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg=
 github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg=
@@ -160,40 +158,36 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/aws/aws-sdk-go v1.51.6 h1:Ld36dn9r7P9IjU8WZSaswQ8Y/XUCRpewim5980DwYiU=
 github.com/aws/aws-sdk-go v1.51.6/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
-github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM=
 github.com/aws/aws-sdk-go-v2 v1.27.0 h1:7bZWKoXhzI+mMR/HjdMx8ZCC5+6fY0lS5tr0bbgiLlo=
 github.com/aws/aws-sdk-go-v2 v1.27.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
-github.com/aws/aws-sdk-go-v2/config v1.27.15 h1:uNnGLZ+DutuNEkuPh6fwqK7LpEiPmzb7MIMA1mNWEUc=
-github.com/aws/aws-sdk-go-v2/config v1.27.15/go.mod h1:7j7Kxx9/7kTmL7z4LlhwQe63MYEE5vkVV6nWg4ZAI8M=
-github.com/aws/aws-sdk-go-v2/credentials v1.17.15 h1:YDexlvDRCA8ems2T5IP1xkMtOZ1uLJOCJdTr0igs5zo=
-github.com/aws/aws-sdk-go-v2/credentials v1.17.15/go.mod h1:vxHggqW6hFNaeNC0WyXS3VdyjcV0a4KMUY4dKJ96buU=
+github.com/aws/aws-sdk-go-v2/config v1.27.16 h1:knpCuH7laFVGYTNd99Ns5t+8PuRjDn4HnnZK48csipM=
+github.com/aws/aws-sdk-go-v2/config v1.27.16/go.mod h1:vutqgRhDUktwSge3hrC3nkuirzkJ4E/mLj5GvI0BQas=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.16 h1:7d2QxY83uYl0l58ceyiSpxg9bSbStqBC6BeEeHEchwo=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.16/go.mod h1:Ae6li/6Yc6eMzysRL2BXlPYvnrLLBg3D11/AmOjw50k=
 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.3 h1:dQLK4TjtnlRGb0czOht2CevZ5l6RSyRWAnKeGd7VAFE=
 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.3/go.mod h1:TL79f2P6+8Q7dTsILpiVST+AL9lkF6PPGI167Ny0Cjw=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7 h1:lf/8VTF2cM+N4SLzaYJERKEWAXq8MOMpZfU6wEPWsPk=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7/go.mod h1:4SjkU7QiqK2M9oozyMzfZ/23LmUY+h3oFqhdeP5OMiI=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8=
 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7 h1:4OYVp0705xu8yjdyoWix0r9wPIRXnIzzOoUpQVHIJ/g=
 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7/go.mod h1:vd7ESTEvI76T2Na050gODNmNU7+OyKrIKroYTu4ABiI=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
-github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2 h1:y6LX9GUoEA3mO0qpFl1ZQHj1rFyPWVphlzebiSt2tKE=
-github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2/go.mod h1:Q0LcmaN/Qr8+4aSBrdrXXePqoX0eOuYpJLbYpilmWnA=
-github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 h1:PpbXaecV3sLAS6rjQiaKw4/jyq3Z8gNzmoJupHAoBp0=
-github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2/go.mod h1:fUHpGXr4DrXkEDpGAjClPsviWf+Bszeb0daKE0blxv8=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.28.3 h1:NsP8PA4Kw1sA6UKl3ZFRIcA9dWomePbmoRIvfOl+HKs=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.28.3/go.mod h1:X52zjAVRaXklEU1TE/wO8kyyJSr9cJx9ZsqliWbyRys=
+github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.7 h1:dsmihXaPkhFuUTiL+ygm9RtUYEmhOeIl7DXNIHCoKDg=
+github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.7/go.mod h1:g7If3uXj+mKcmIuxh08qh8I9ju6f/aOSWMyc6hEEi58=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9 h1:Wx0rlZoEJR7JwlSZcHnEa7CNjrSIyVxMFWGAaXy4fJY=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9/go.mod h1:aVMHdE0aHO3v+f/iw01fmXV/5DbfQ3Bi9nN7nd9bE9Y=
-github.com/aws/aws-sdk-go-v2/service/kms v1.30.0 h1:yS0JkEdV6h9JOo8sy2JSpjX+i7vsKifU8SIeHrqiDhU=
-github.com/aws/aws-sdk-go-v2/service/kms v1.30.0/go.mod h1:+I8VUUSVD4p5ISQtzpgSva4I8cJ4SQ4b1dcBcof7O+g=
-github.com/aws/aws-sdk-go-v2/service/sso v1.20.8 h1:Kv1hwNG6jHC/sxMTe5saMjH6t6ZLkgfvVxyEjfWL1ks=
-github.com/aws/aws-sdk-go-v2/service/sso v1.20.8/go.mod h1:c1qtZUWtygI6ZdvKppzCSXsDOq5I4luJPZ0Ud3juFCA=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.2 h1:nWBZ1xHCF+A7vv9sDzJOq4NWIdzFYm0kH7Pr4OjHYsQ=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.2/go.mod h1:9lmoVDVLz/yUZwLaQ676TK02fhCu4+PgRSmMaKR1ozk=
-github.com/aws/aws-sdk-go-v2/service/sts v1.28.9 h1:Qp6Boy0cGDloOE3zI6XhNLNZgjNS8YmiFQFHe71SaW0=
-github.com/aws/aws-sdk-go-v2/service/sts v1.28.9/go.mod h1:0Aqn1MnEuitqfsCNyKsdKLhDUOr4txD/g19EfiUqgws=
-github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
+github.com/aws/aws-sdk-go-v2/service/kms v1.31.3 h1:wLBgq6nDNYdd0A5CvscVAKV5SVlHKOHVPedpgtigATg=
+github.com/aws/aws-sdk-go-v2/service/kms v1.31.3/go.mod h1:8lETO9lelSG2B6KMXFh2OwPPqGV6WQM3RqLAEjP1xaU=
+github.com/aws/aws-sdk-go-v2/service/sso v1.20.9 h1:aD7AGQhvPuAxlSUfo0CWU7s6FpkbyykMhGYMvlqTjVs=
+github.com/aws/aws-sdk-go-v2/service/sso v1.20.9/go.mod h1:c1qtZUWtygI6ZdvKppzCSXsDOq5I4luJPZ0Ud3juFCA=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3 h1:Pav5q3cA260Zqez42T9UhIlsd9QeypszRPwC9LdSSsQ=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3/go.mod h1:9lmoVDVLz/yUZwLaQ676TK02fhCu4+PgRSmMaKR1ozk=
+github.com/aws/aws-sdk-go-v2/service/sts v1.28.10 h1:69tpbPED7jKPyzMcrwSvhWcJ9bPnZsZs18NT40JwM0g=
+github.com/aws/aws-sdk-go-v2/service/sts v1.28.10/go.mod h1:0Aqn1MnEuitqfsCNyKsdKLhDUOr4txD/g19EfiUqgws=
 github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q=
 github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
 github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 h1:SoFYaT9UyGkR0+nogNyD/Lj+bsixB+SNuAS4ABlEs6M=
@@ -318,8 +312,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
 github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
 github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
-github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE=
-github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
+github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA=
+github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
 github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
 github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
 github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
@@ -338,8 +332,8 @@ github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A
 github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc=
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
-github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
@@ -366,8 +360,8 @@ github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3Bum
 github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
 github.com/go-piv/piv-go v1.11.0 h1:5vAaCdRTFSIW4PeqMbnsDlUZ7odMYWnHBDGdmtU/Zhg=
 github.com/go-piv/piv-go v1.11.0/go.mod h1:NZ2zmjVkfFaL/CF8cVQ/pXdXtuj110zEKGdJM6fJZZM=
-github.com/go-rod/rod v0.114.7 h1:h4pimzSOUnw7Eo41zdJA788XsawzHjJMyzCE3BrBww0=
-github.com/go-rod/rod v0.114.7/go.mod h1:aiedSEFg5DwG/fnNbUOTPMTTWX3MRj6vIs/a684Mthw=
+github.com/go-rod/rod v0.116.0 h1:ypRryjTys3EnqHskJ/TdgodFMvXV0EHvmy4bSkKZgHM=
+github.com/go-rod/rod v0.116.0/go.mod h1:aiedSEFg5DwG/fnNbUOTPMTTWX3MRj6vIs/a684Mthw=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
@@ -439,7 +433,6 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -591,8 +584,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/notaryproject/notation-core-go v1.0.2 h1:VEt+mbsgdANd9b4jqgmx2C7U0DmwynOuD2Nhxh3bANw=
-github.com/notaryproject/notation-core-go v1.0.2/go.mod h1:2HkQzUwg08B3x9oVIztHsEh7Vil2Rj+tYgxH+JObLX4=
+github.com/notaryproject/notation-core-go v1.0.3 h1:FCgvULSypEFrrNgvDRdHbKAGAgbXK43n/jKD9q2WECA=
+github.com/notaryproject/notation-core-go v1.0.3/go.mod h1:eDo5/LTUp23mB7w0CckJLnl+p93oGdyiKDzzggpqTH4=
 github.com/notaryproject/notation-go v1.0.1 h1:D3fqG3eaBKVESRySV/Tg//MyTg2Q1nTKPh/t2q9LpSw=
 github.com/notaryproject/notation-go v1.0.1/go.mod h1:VonyZsbocRQQNIDq/VPV5jKJOQwDH3gvfK4cXNpUA0U=
 github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 h1:Up6+btDp321ZG5/zdSLo48H9Iaq0UQGthrhWC6pCxzE=
@@ -687,8 +680,8 @@ github.com/sigstore/fulcio v1.4.5 h1:WWNnrOknD0DbruuZWCbN+86WRROpEl3Xts+WT2Ek1yc
 github.com/sigstore/fulcio v1.4.5/go.mod h1:oz3Qwlma8dWcSS/IENR/6SjbW4ipN0cxpRVfgdsjMU8=
 github.com/sigstore/rekor v1.3.6 h1:QvpMMJVWAp69a3CHzdrLelqEqpTM3ByQRt5B5Kspbi8=
 github.com/sigstore/rekor v1.3.6/go.mod h1:JDTSNNMdQ/PxdsS49DJkJ+pRJCO/83nbR5p3aZQteXc=
-github.com/sigstore/sigstore v1.8.3 h1:G7LVXqL+ekgYtYdksBks9B38dPoIsbscjQJX/MGWkA4=
-github.com/sigstore/sigstore v1.8.3/go.mod h1:mqbTEariiGA94cn6G3xnDiV6BD8eSLdL/eA7bvJ0fVs=
+github.com/sigstore/sigstore v1.8.4 h1:g4ICNpiENFnWxjmBzBDWUn62rNFeny/P77HUC8da32w=
+github.com/sigstore/sigstore v1.8.4/go.mod h1:1jIKtkTFEeISen7en+ZPWdDHazqhxco/+v9CNjc7oNg=
 github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.3 h1:LTfPadUAo+PDRUbbdqbeSl2OuoFQwUFTnJ4stu+nwWw=
 github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.3/go.mod h1:QV/Lxlxm0POyhfyBtIbTWxNeF18clMlkkyL9mu45y18=
 github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3 h1:xgbPRCr2npmmsuVVteJqi/ERw9+I13Wou7kq0Yk4D8g=
@@ -860,9 +853,10 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
 golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
-golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
-golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
+golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -950,8 +944,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
-golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
+golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
+golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1019,9 +1013,10 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
-golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@@ -1030,9 +1025,10 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
 golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
+golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
 golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
-golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
-golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
+golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1047,8 +1043,9 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/helmfile.yaml b/helmfile.yaml
index 310facf..be9cecf 100644
--- a/helmfile.yaml
+++ b/helmfile.yaml
@@ -2,14 +2,14 @@ repositories:
   - name: gatekeeper
     url: https://open-policy-agent.github.io/gatekeeper/charts
   - name: ratify
-    url: https://deislabs.github.io/ratify
-    
+    url: https://ratify-project.github.io/ratify
+
 releases:
   - name: gatekeeper
     namespace: gatekeeper-system
     createNamespace: true
     chart: gatekeeper/gatekeeper
-    version: 3.14.0
+    version: 3.16.0
     wait: true
     set:
       - name: enableExternalData
@@ -23,7 +23,7 @@ releases:
   - name: ratify
     namespace: gatekeeper-system
     chart: ratify/ratify
-    version: 1.12.1 # Make sure this matches Chart.yaml
+    version: 1.13.0 # Make sure this matches Chart.yaml
     wait: true
     needs:
       - gatekeeper
@@ -33,14 +33,14 @@ releases:
         command: "bash"
         args:
           - "-c"
-          - "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"
+          - "kubectl apply -f https://ratify-project.github.io/ratify/library/default/template.yaml && kubectl apply -f https://ratify-project.github.io/ratify/library/default/samples/constraint.yaml"
       - events: ["postuninstall"]
         showlogs: true
         command: "kubectl"
         args:
           - "delete"
           - "-f"
-          - "https://deislabs.github.io/ratify/library/default/template.yaml"
+          - "https://ratify-project.github.io/ratify/library/default/template.yaml"
           - "--ignore-not-found=true"
       - events: ["postuninstall"]
         showlogs: true
@@ -48,7 +48,7 @@ releases:
         args:
           - "delete"
           - "-f"
-          - "https://deislabs.github.io/ratify/library/default/samples/constraint.yaml"
+          - "https://ratify-project.github.io/ratify/library/default/samples/constraint.yaml"
           - "--ignore-not-found=true"
       - events: ["postuninstall"]
         showlogs: true
@@ -60,6 +60,11 @@ releases:
           - "verifiers.config.ratify.deislabs.io"
           - "certificatestores.config.ratify.deislabs.io"
           - "policies.config.ratify.deislabs.io"
+          - "keymanagementproviders.config.ratify.deislabs.io"
+          - "namespacedkeymanagementproviders.config.ratify.deislabs.io"
+          - "namespacedpolicies.config.ratify.deislabs.io"
+          - "namespacedstores.config.ratify.deislabs.io"
+          - "namespacedverifiers.config.ratify.deislabs.io"
       - events: ["postuninstall"]
         showlogs: true
         command: "kubectl"
@@ -70,7 +75,7 @@ releases:
           - "-n"
           - "gatekeeper-system"
     set:
-      - name: notationCert
+      - name: notationCerts[0]
         value: {{ exec "curl" (list "-sSL" "https://raw.githubusercontent.com/deislabs/ratify/main/test/testdata/notation.crt") | quote }}
       - name: featureFlags.RATIFY_CERT_ROTATION
         value: true
diff --git a/high-availability.helmfile.yaml b/high-availability.helmfile.yaml
index f99e1b9..331d88a 100644
--- a/high-availability.helmfile.yaml
+++ b/high-availability.helmfile.yaml
@@ -1,20 +1,38 @@
 repositories:
+  - name: gatekeeper
+    url: https://open-policy-agent.github.io/gatekeeper/charts
   - name: dapr
     url: https://dapr.github.io/helm-charts/
   - name: bitnami
     url: https://charts.bitnami.com/bitnami
   - name: ratify
-    url: https://deislabs.github.io/ratify
+    url: https://ratify-project.github.io/ratify
     
 releases:
   - name: dapr
     namespace: dapr-system
     createNamespace: true
     chart: dapr/dapr
-    version: 1.11.1
+    version: 1.13.2
     wait: true
+  - name: gatekeeper
+    namespace: gatekeeper-system
+    createNamespace: true
+    chart: gatekeeper/gatekeeper
+    version: 3.16.0
+    wait: true
+    set:
+      - name: enableExternalData
+        value: true
+      - name: validatingWebhookTimeoutSeconds
+        value: 5
+      - name: mutatingWebhookTimeoutSeconds
+        value: 2
+      - name: externaldataProviderResponseCacheTTL
+        value: 10s
   - name: redis
     namespace: gatekeeper-system
+    createNamespace: true
     chart: bitnami/redis
     version: 17.11.6
     wait: true
@@ -32,11 +50,12 @@ releases:
   - name: ratify
     namespace: gatekeeper-system
     chart: ratify/ratify
-    version: 1.12.1 # Make sure this matches Chart.yaml
+    version: 1.13.0 # Make sure this matches Chart.yaml
     wait: true
     needs:
       - dapr-system/dapr
       - gatekeeper-system/redis
+      - gatekeeper-system/gatekeeper
     hooks:
       - events: ["presync"]
         showlogs: true
@@ -53,6 +72,12 @@ releases:
           - "https://raw.githubusercontent.com/deislabs/ratify/main/test/testdata/dapr/dapr-redis.yaml"
           - "-n"
           - "gatekeeper-system"
+      - events: ["presync"]
+        showlogs: true
+        command: "bash"
+        args:
+          - "-c"
+          - "kubectl apply -f https://ratify-project.github.io/ratify/library/default/template.yaml && kubectl apply -f https://ratify-project.github.io/ratify/library/default/samples/constraint.yaml"
       - events: ["postuninstall"]
         showlogs: true
         command: "kubectl"
@@ -79,7 +104,7 @@ releases:
         args:
           - "delete"
           - "-f"
-          - "https://deislabs.github.io/ratify/library/default/template.yaml"
+          - "https://ratify-project.github.io/ratify/library/default/template.yaml"
           - "--ignore-not-found=true"
       - events: ["postuninstall"]
         showlogs: true
@@ -87,7 +112,7 @@ releases:
         args:
           - "delete"
           - "-f"
-          - "https://deislabs.github.io/ratify/library/default/samples/constraint.yaml"
+          - "https://ratify-project.github.io/ratify/library/default/samples/constraint.yaml"
           - "--ignore-not-found=true"
       - events: ["postuninstall"]
         showlogs: true
@@ -99,6 +124,10 @@ releases:
           - "verifiers.config.ratify.deislabs.io"
           - "certificatestores.config.ratify.deislabs.io"
           - "policies.config.ratify.deislabs.io"
+          - "namespacedkeymanagementproviders.config.ratify.deislabs.io"
+          - "namespacedpolicies.config.ratify.deislabs.io"
+          - "namespacedstores.config.ratify.deislabs.io"
+          - "namespacedverifiers.config.ratify.deislabs.io"
       - events: ["postuninstall"]
         showlogs: true
         command: "kubectl"
@@ -115,7 +144,7 @@ releases:
         value: true
       - name: logger.level
         value: debug
-      - name: notationCert
+      - name: notationCerts[0]
         value: {{ exec "curl" (list "-sSL" "https://raw.githubusercontent.com/deislabs/ratify/main/test/testdata/notation.crt") | quote }}
       - name: replicaCount
         value: 2
diff --git a/httpserver/Dockerfile b/httpserver/Dockerfile
index 8e434f1..be47fd9 100644
--- a/httpserver/Dockerfile
+++ b/httpserver/Dockerfile
@@ -11,7 +11,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM --platform=$BUILDPLATFORM golang:1.21@sha256:16438a8e66c0c984f732e815ee5b7d715b8e33e81bac6d6a3750b1067744e7ca as builder
+FROM --platform=$BUILDPLATFORM golang:1.21@sha256:a8edec58ba598e2f1259f4ec4ca1b06358468214225e73d7c841ab0980c12367 as builder
 
 ARG TARGETPLATFORM
 ARG TARGETOS
diff --git a/library/default/customazurepolicy.json b/library/default/customazurepolicy.json
index 52b16c5..6572fff 100644
--- a/library/default/customazurepolicy.json
+++ b/library/default/customazurepolicy.json
@@ -106,7 +106,7 @@
             "details": {
                 "templateInfo": {
                     "sourceType": "PublicURL",
-                    "url": "https://deislabs.github.io/ratify/library/default/template.yaml"
+                    "url": "https://ratify-project.github.io/ratify/library/default/template.yaml"
                 },
                 "apiGroups": [
                     ""
diff --git a/pkg/verifier/cosign/cosign.go b/pkg/verifier/cosign/cosign.go
index 1f365aa..34b0e3c 100644
--- a/pkg/verifier/cosign/cosign.go
+++ b/pkg/verifier/cosign/cosign.go
@@ -79,6 +79,7 @@ type LegacyExtension struct {
 // where each entry corresponds to a single signature verified
 type Extension struct {
 	SignatureExtension []cosignExtensionList `json:"signatures,omitempty"`
+	TrustPolicy        string                `json:"trustPolicy,omitempty"`
 }
 
 // cosignExtensionList is the structure verifications performed
@@ -97,6 +98,7 @@ type cosignExtension struct {
 	BundleVerified  bool          `json:"bundleVerified"`
 	Err             string        `json:"error,omitempty"`
 	KeyInformation  PKKey         `json:"keyInformation,omitempty"`
+	Summary         []string      `json:"summary,omitempty"`
 }
 
 type cosignVerifier struct {
@@ -117,9 +119,19 @@ var logOpt = logger.Option{
 }
 
 // used for mocking purposes
-var getKeysMaps = getKeysMapsDefault
-
-const verifierType string = "cosign"
+var getKeyMapOpts = getKeyMapOptsDefault
+
+const (
+	verifierType string = "cosign"
+	// messages for verificationPerformedMessage. source: https://github.com/sigstore/cosign/blob/d275a272ec0cdf5a4c22d01b891a4d7e20164d71/cmd/cosign/cli/verify/verify.go#L318
+	annotationMessage    string = "The specified annotations were verified."                                                    // TODO: check if message has been updated by upstream cosign cli
+	claimsMessage        string = "The cosign claims were validated."                                                           // TODO: check if message has been updated by upstream cosign cli
+	offlineBundleMessage string = "Existence of the claims in the transparency log was verified offline."                       // TODO: check if message has been updated by upstream cosign cli
+	rekorClaimsMessage   string = "The claims were present in the transparency log."                                            // TODO: check if message has been updated by upstream cosign cli
+	rekorSigMessage      string = "The signatures were integrated into the transparency log when the certificate was valid."    // TODO: check if message has been updated by upstream cosign cli
+	sigVerifierMessage   string = "The signatures were verified against the specified public key."                              // TODO: check if message has been updated by upstream cosign cli
+	certVerifierMessage  string = "The code-signing certificate was verified using trusted certificate authority certificates." // TODO: check if message has been updated by upstream cosign cli
+)
 
 // init() registers the cosign verifier with the factory
 func init() {
@@ -148,6 +160,7 @@ func (f *cosignVerifierFactory) Create(_ string, verifierConfig config.VerifierC
 	legacy := true
 	// if trustPolicies are provided and non-legacy, create the trust policies
 	if config.KeyRef == "" && config.RekorURL == "" && len(config.TrustPolicies) > 0 {
+		logger.GetLogger(context.Background(), logOpt).Debugf("legacy cosign verifier configuration not found, creating trust policies")
 		trustPolicies, err = CreateTrustPolicies(config.TrustPolicies, verifierName)
 		if err != nil {
 			return nil, err
@@ -195,8 +208,15 @@ func (v *cosignVerifier) Verify(ctx context.Context, subjectReference common.Ref
 }
 
 func (v *cosignVerifier) verifyInternal(ctx context.Context, subjectReference common.Reference, referenceDescriptor ocispecs.ReferenceDescriptor, referrerStore referrerstore.ReferrerStore) (verifier.VerifierResult, error) {
+	// get the trust policy for the reference
+	trustPolicy, err := v.trustPolicies.GetScopedPolicy(subjectReference.Original)
+	if err != nil {
+		return errorToVerifyResult(v.name, v.verifierType, err), nil
+	}
+	logger.GetLogger(ctx, logOpt).Debugf("selected trust policy %s for reference %s", trustPolicy.GetName(), subjectReference.Original)
+
 	// get the map of keys and relevant cosign options for that reference
-	keysMap, cosignOpts, err := getKeysMaps(ctx, v.trustPolicies, subjectReference.Original, v.namespace)
+	keysMap, cosignOpts, err := getKeyMapOpts(ctx, trustPolicy, v.namespace)
 	if err != nil {
 		return errorToVerifyResult(v.name, v.verifierType, err), nil
 	}
@@ -246,41 +266,20 @@ func (v *cosignVerifier) verifyInternal(ctx context.Context, subjectReference co
 		if err != nil {
 			return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("failed to generate static signature: %w", err)), nil
 		}
-		// check each key in the map of keys returned by the trust policy
-		for mapKey, pubKey := range keysMap {
-			hashType := crypto.SHA256
-			// default hash type is SHA256 but for AKV scenarios, the hash type is determined by the key size
-			// TODO: investigate if it's possible to extract hash type from sig directly. This is a workaround for now
-			if pubKey.ProviderType == azurekeyvault.ProviderName {
-				hashType, sig, err = processAKVSignature(blob.Annotations[static.SignatureAnnotationKey], sig, pubKey.Key, blobBytes, staticOpts)
-				if err != nil {
-					return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("failed to process AKV signature: %w", err)), nil
-				}
-			}
-
-			// return the correct verifier based on public key type and bytes
-			verifier, err := signature.LoadVerifier(pubKey.Key, hashType)
-			if err != nil {
-				return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("failed to load public key from provider [%s] name [%s] version [%s]: %w", mapKey.Provider, mapKey.Name, mapKey.Version, err)), nil
-			}
-			cosignOpts.SigVerifier = verifier
-			// verify signature with cosign options + perform bundle verification
-			bundleVerified, err := cosign.VerifyImageSignature(ctx, sig, subjectDescHash, &cosignOpts)
-			extension := cosignExtension{
-				IsSuccess:      true,
-				BundleVerified: bundleVerified,
-				KeyInformation: mapKey,
-			}
+		if len(keysMap) > 0 {
+			// if keys are found, perform verification with keys
+			var verifications []cosignExtension
+			verifications, hasValidSignature, err = verifyWithKeys(ctx, keysMap, sig, blob.Annotations[static.SignatureAnnotationKey], blobBytes, staticOpts, &cosignOpts, subjectDescHash)
 			if err != nil {
-				extension.IsSuccess = false
-				extension.Err = err.Error()
-			} else {
-				hasValidSignature = true
+				return errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("failed to verify with keys: %w", err)), nil
 			}
+			extensionListEntry.Verifications = append(extensionListEntry.Verifications, verifications...)
+		} else {
+			// if no keys are found, perform keyless verification
+			var extension cosignExtension
+			extension, hasValidSignature = verifyKeyless(ctx, sig, &cosignOpts, subjectDescHash)
 			extensionListEntry.Verifications = append(extensionListEntry.Verifications, extension)
 		}
-
-		// TODO: perform keyless verification instead if no keys are found
 		sigExtensions = append(sigExtensions, extensionListEntry)
 	}
 
@@ -290,12 +289,12 @@ func (v *cosignVerifier) verifyInternal(ctx context.Context, subjectReference co
 			Type:       v.verifierType,
 			IsSuccess:  true,
 			Message:    "cosign verification success. valid signatures found. please refer to extensions field for verifications performed.",
-			Extensions: Extension{SignatureExtension: sigExtensions},
+			Extensions: Extension{SignatureExtension: sigExtensions, TrustPolicy: trustPolicy.GetName()},
 		}, nil
 	}
 
 	errorResult := errorToVerifyResult(v.name, v.verifierType, fmt.Errorf("no valid signatures found"))
-	errorResult.Extensions = Extension{SignatureExtension: sigExtensions}
+	errorResult.Extensions = Extension{SignatureExtension: sigExtensions, TrustPolicy: trustPolicy.GetName()}
 	return errorResult, nil
 }
 
@@ -520,15 +519,69 @@ func decodeASN1Signature(sig []byte) ([]byte, error) {
 	return rawSigBytes, nil
 }
 
-// getKeysMapsDefault returns the map of keys and cosign options for the reference
-func getKeysMapsDefault(ctx context.Context, trustPolicies *TrustPolicies, reference string, namespace string) (map[PKKey]keymanagementprovider.PublicKey, cosign.CheckOpts, error) {
-	// get the trust policy for the reference
-	trustPolicy, err := trustPolicies.GetScopedPolicy(reference)
+// verifyWithKeys verifies the signature with the keys map and returns the verification results
+func verifyWithKeys(ctx context.Context, keysMap map[PKKey]keymanagementprovider.PublicKey, sig oci.Signature, sigEncoded string, payload []byte, staticOpts []static.Option, cosignOpts *cosign.CheckOpts, subjectDescHash v1.Hash) ([]cosignExtension, bool, error) {
+	// check each key in the map of keys returned by the trust policy
+	var err error
+	verifications := make([]cosignExtension, 0)
+	hasValidSignature := false
+	for mapKey, pubKey := range keysMap {
+		hashType := crypto.SHA256
+		// default hash type is SHA256 but for AKV scenarios, the hash type is determined by the key size
+		// TODO: investigate if it's possible to extract hash type from sig directly. This is a workaround for now
+		if pubKey.ProviderType == azurekeyvault.ProviderName {
+			hashType, sig, err = processAKVSignature(sigEncoded, sig, pubKey.Key, payload, staticOpts)
+			if err != nil {
+				return verifications, false, fmt.Errorf("failed to process AKV signature: %w", err)
+			}
+		}
+
+		// return the correct verifier based on public key type and bytes
+		verifier, err := signature.LoadVerifier(pubKey.Key, hashType)
+		if err != nil {
+			return verifications, false, fmt.Errorf("failed to load public key from provider [%s] name [%s] version [%s]: %w", mapKey.Provider, mapKey.Name, mapKey.Version, err)
+		}
+		cosignOpts.SigVerifier = verifier
+		// verify signature with cosign options + perform bundle verification
+		bundleVerified, err := cosign.VerifyImageSignature(ctx, sig, subjectDescHash, cosignOpts)
+		extension := cosignExtension{
+			IsSuccess:      true,
+			BundleVerified: bundleVerified,
+			KeyInformation: mapKey,
+		}
+		if err != nil {
+			extension.IsSuccess = false
+			extension.Err = err.Error()
+		} else {
+			extension.Summary = verificationPerformedMessage(bundleVerified, cosignOpts)
+			hasValidSignature = true
+		}
+		verifications = append(verifications, extension)
+	}
+	return verifications, hasValidSignature, nil
+}
+
+// verifyKeyless performs keyless verification and returns the verification results
+func verifyKeyless(ctx context.Context, sig oci.Signature, cosignOpts *cosign.CheckOpts, subjectDescHash v1.Hash) (cosignExtension, bool) {
+	// verify signature with cosign options + perform bundle verification
+	hasValidSignature := false
+	bundleVerified, err := cosign.VerifyImageSignature(ctx, sig, subjectDescHash, cosignOpts)
+	extension := cosignExtension{
+		IsSuccess:      true,
+		BundleVerified: bundleVerified,
+	}
 	if err != nil {
-		return nil, cosign.CheckOpts{}, err
+		extension.IsSuccess = false
+		extension.Err = err.Error()
+	} else {
+		extension.Summary = verificationPerformedMessage(bundleVerified, cosignOpts)
+		hasValidSignature = true
 	}
-	logger.GetLogger(ctx, logOpt).Debugf("selected trust policy %s for reference %s", trustPolicy.GetName(), reference)
+	return extension, hasValidSignature
+}
 
+// getKeyMapOptsDefault returns the map of keys and cosign options for the reference
+func getKeyMapOptsDefault(ctx context.Context, trustPolicy TrustPolicy, namespace string) (map[PKKey]keymanagementprovider.PublicKey, cosign.CheckOpts, error) {
 	// get the map of keys for that reference
 	keysMap, err := trustPolicy.GetKeys(ctx, namespace)
 	if err != nil {
@@ -594,3 +647,28 @@ func processAKVSignature(sigEncoded string, staticSig oci.Signature, publicKey c
 	}
 	return hashType, staticSig, nil
 }
+
+// verificationPerformedMessage returns a string list of all verifications performed
+// based on https://github.com/sigstore/cosign/blob/5ae2e31c30ee87e035cc57ebbbe2ecf3b6549ff5/cmd/cosign/cli/verify/verify.go#L318
+func verificationPerformedMessage(bundleVerified bool, co *cosign.CheckOpts) []string {
+	var messages []string
+	if co.ClaimVerifier != nil {
+		if co.Annotations != nil {
+			messages = append(messages, annotationMessage)
+		}
+		messages = append(messages, claimsMessage)
+	}
+	if bundleVerified {
+		messages = append(messages, offlineBundleMessage)
+	} else if co.RekorClient != nil {
+		messages = append(messages, rekorClaimsMessage)
+		messages = append(messages, rekorSigMessage)
+	}
+	// if no SigVerifier is provided, fulcio root certs are assumed to be used (keyless)
+	if co.SigVerifier != nil {
+		messages = append(messages, sigVerifierMessage)
+	} else {
+		messages = append(messages, certVerifierMessage)
+	}
+	return messages
+}
diff --git a/pkg/verifier/cosign/trustpolicy.go b/pkg/verifier/cosign/trustpolicy.go
index 08410ae..7efe269 100644
--- a/pkg/verifier/cosign/trustpolicy.go
+++ b/pkg/verifier/cosign/trustpolicy.go
@@ -39,8 +39,11 @@ type KeyConfig struct {
 }
 
 type KeylessConfig struct {
-	RekorURL    string `json:"rekorURL,omitempty"`
-	CTLogVerify *bool  `json:"ctLogVerify,omitempty"`
+	CTLogVerify                 *bool  `json:"ctLogVerify,omitempty"`
+	CertificateIdentity         string `json:"certificateIdentity,omitempty"`
+	CertificateIdentityRegExp   string `json:"certificateIdentityRegExp,omitempty"`
+	CertificateOIDCIssuer       string `json:"certificateOIDCIssuer,omitempty"`
+	CertificateOIDCIssuerRegExp string `json:"certificateOIDCIssuerRegExp,omitempty"`
 }
 
 type TrustPolicyConfig struct {
@@ -50,10 +53,11 @@ type TrustPolicyConfig struct {
 	Keys       []KeyConfig   `json:"keys,omitempty"`
 	Keyless    KeylessConfig `json:"keyless,omitempty"`
 	TLogVerify *bool         `json:"tLogVerify,omitempty"`
+	RekorURL   string        `json:"rekorURL,omitempty"`
 }
 
 type PKKey struct {
-	Provider string `json:"provider"`
+	Provider string `json:"provider,omitempty"`
 	Name     string `json:"name,omitempty"`
 	Version  string `json:"version,omitempty"`
 }
@@ -109,8 +113,8 @@ func CreateTrustPolicy(config TrustPolicyConfig, verifierName string) (TrustPoli
 		}
 	}
 
-	if config.Keyless.RekorURL == "" {
-		config.Keyless.RekorURL = DefaultRekorURL
+	if config.RekorURL == "" {
+		config.RekorURL = DefaultRekorURL
 	}
 
 	if config.TLogVerify == nil {
@@ -177,16 +181,31 @@ func (tp *trustPolicy) GetScopes() []string {
 
 func (tp *trustPolicy) GetCosignOpts(ctx context.Context) (cosign.CheckOpts, error) {
 	cosignOpts := cosign.CheckOpts{}
+	var err error
+	// if tlog verification is enabled, set the rekor client and public keys
+	if tp.config.TLogVerify != nil && *tp.config.TLogVerify {
+		cosignOpts.IgnoreTlog = false
+		// create the rekor client
+		cosignOpts.RekorClient, err = rekor.NewClient(tp.config.RekorURL)
+		if err != nil {
+			return cosignOpts, fmt.Errorf("failed to create Rekor client from URL %s: %w", tp.config.RekorURL, err)
+		}
+		// Fetches the Rekor public keys from the Rekor server
+		cosignOpts.RekorPubKeys, err = cosign.GetRekorPubs(ctx)
+		if err != nil {
+			return cosignOpts, fmt.Errorf("failed to fetch Rekor public keys: %w", err)
+		}
+	} else {
+		cosignOpts.IgnoreTlog = true
+	}
+
+	// if keyless verification is enabled, set the root certificates, intermediate certificates, and certificate transparency log public keys
 	if tp.isKeyless {
 		roots, err := fulcio.GetRoots()
 		if err != nil || roots == nil {
 			return cosignOpts, fmt.Errorf("failed to get fulcio roots: %w", err)
 		}
 		cosignOpts.RootCerts = roots
-		cosignOpts.RekorClient, err = rekor.NewClient(tp.config.Keyless.RekorURL)
-		if err != nil {
-			return cosignOpts, fmt.Errorf("failed to create Rekor client from URL %s: %w", tp.config.Keyless.RekorURL, err)
-		}
 		if tp.config.Keyless.CTLogVerify != nil && *tp.config.Keyless.CTLogVerify {
 			cosignOpts.CTLogPubKeys, err = cosign.GetCTLogPubs(ctx)
 			if err != nil {
@@ -195,19 +214,21 @@ func (tp *trustPolicy) GetCosignOpts(ctx context.Context) (cosign.CheckOpts, err
 		} else {
 			cosignOpts.IgnoreSCT = true
 		}
-		// Fetches the Rekor public keys from the Rekor server
-		cosignOpts.RekorPubKeys, err = cosign.GetRekorPubs(ctx)
-		if err != nil {
-			return cosignOpts, fmt.Errorf("failed to fetch Rekor public keys: %w", err)
-		}
 		cosignOpts.IntermediateCerts, err = fulcio.GetIntermediates()
 		if err != nil {
 			return cosignOpts, fmt.Errorf("failed to get fulcio intermediate certificates: %w", err)
 		}
+		// Set the certificate identity and issuer for keyless verification
+		cosignOpts.Identities = []cosign.Identity{
+			{
+				IssuerRegExp:  tp.config.Keyless.CertificateOIDCIssuerRegExp,
+				Issuer:        tp.config.Keyless.CertificateOIDCIssuer,
+				SubjectRegExp: tp.config.Keyless.CertificateIdentityRegExp,
+				Subject:       tp.config.Keyless.CertificateIdentity,
+			},
+		}
 	}
-	if tp.config.TLogVerify != nil && *tp.config.TLogVerify {
-		cosignOpts.IgnoreTlog = true
-	}
+
 	return cosignOpts, nil
 }
 
@@ -246,16 +267,32 @@ func validate(config TrustPolicyConfig, verifierName string) error {
 		if keyConfig.File != "" && keyConfig.Provider != "" {
 			return re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName).WithDetail(fmt.Sprintf("trust policy %s failed: 'name' and 'file' cannot be configured together", config.Name))
 		}
-		// key management provider is required when specific keys are configured
-		if keyConfig.Name != "" && keyConfig.Provider == "" {
-			return re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName).WithDetail(fmt.Sprintf("trust policy %s failed: key management provider name is required when key name is defined", config.Name))
-		}
 		// key name is required when key version is defined
 		if keyConfig.Version != "" && keyConfig.Name == "" {
 			return re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName).WithDetail(fmt.Sprintf("trust policy %s failed: key name is required when key version is defined", config.Name))
 		}
 	}
 
+	// validate keyless configuration
+	if config.Keyless != (KeylessConfig{}) {
+		// validate certificate identity specified
+		if config.Keyless.CertificateIdentity == "" && config.Keyless.CertificateIdentityRegExp == "" {
+			return re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName).WithDetail(fmt.Sprintf("trust policy %s failed: certificate identity or identity regex pattern is required", config.Name))
+		}
+		// validate certificate OIDC issuer specified
+		if config.Keyless.CertificateOIDCIssuer == "" && config.Keyless.CertificateOIDCIssuerRegExp == "" {
+			return re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName).WithDetail(fmt.Sprintf("trust policy %s failed: certificate OIDC issuer or issuer regex pattern is required", config.Name))
+		}
+		// validate only expression or value is specified for certificate identity
+		if config.Keyless.CertificateIdentity != "" && config.Keyless.CertificateIdentityRegExp != "" {
+			return re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName).WithDetail(fmt.Sprintf("trust policy %s failed: only one of certificate identity or identity regex pattern should be specified", config.Name))
+		}
+		// validate only expression or value is specified for certificate OIDC issuer
+		if config.Keyless.CertificateOIDCIssuer != "" && config.Keyless.CertificateOIDCIssuerRegExp != "" {
+			return re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName).WithDetail(fmt.Sprintf("trust policy %s failed: only one of certificate OIDC issuer or issuer regex pattern should be specified", config.Name))
+		}
+	}
+
 	return nil
 }
 
diff --git a/scripts/create-azure-resources.sh b/scripts/create-azure-resources.sh
index 217ec5b..58a04d2 100755
--- a/scripts/create-azure-resources.sh
+++ b/scripts/create-azure-resources.sh
@@ -23,12 +23,6 @@ set -o pipefail
 : "${AKS_NAME:?AKS_NAME environment variable empty or not defined.}"
 : "${ACR_NAME:?ACR_NAME environment variable empty or not defined.}"
 
-register_feature() {
-  az extension add --name aks-preview
-  az feature register --namespace "Microsoft.ContainerService" --name "EnableWorkloadIdentityPreview"
-  az provider register --namespace Microsoft.ContainerService
-}
-
 create_user_managed_identity() {
   SUBSCRIPTION_ID="$(az account show --query id --output tsv)"
 
@@ -95,15 +89,29 @@ create_akv() {
 
   echo "AKV '${KEYVAULT_NAME}' is created"
 
-  # Grant permissions to access the certificate.
-  az keyvault set-policy --name ${KEYVAULT_NAME} --secret-permissions get --key-permissions get --object-id ${USER_ASSIGNED_IDENTITY_OBJECT_ID}
+  # Grant ratify identity permissions to access the secret
+  az role assignment create \
+    --assignee-object-id ${USER_ASSIGNED_IDENTITY_OBJECT_ID} \
+    --assignee-principal-type "ServicePrincipal" \
+    --role "Key Vault Secrets User" \
+    --scope subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${GROUP_NAME}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}
+  
+  # Grant ratify identity permissions to access keys
+  az role assignment create \
+    --assignee-object-id ${USER_ASSIGNED_IDENTITY_OBJECT_ID} \
+    --assignee-principal-type "ServicePrincipal" \
+    --role "Key Vault Crypto User" \
+    --scope subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${GROUP_NAME}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}
+
+  # Grant runner SP permissions to create keys and import certificates
+  az role assignment create \
+    --assignee-object-id ${AZURE_SP_OBJECT_ID} \
+    --assignee-principal-type "ServicePrincipal" \
+    --role "Key Vault Administrator" \
+    --scope subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${GROUP_NAME}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}
 }
 
 main() {
-  export -f register_feature
-  # might take around 20 minutes to register
-  timeout --foreground 1200 bash -c register_feature
-
   az group create --name "${GROUP_NAME}" --tags "ratifye2e" --location "${LOCATION}" >/dev/null
 
   create_user_managed_identity


Test patch:
diff --git a/.github/workflows/e2e-aks.yml b/.github/workflows/e2e-aks.yml
index 5cc63f6..289cc0e 100644
--- a/.github/workflows/e2e-aks.yml
+++ b/.github/workflows/e2e-aks.yml
@@ -14,7 +14,7 @@ on:
       gatekeeper_version:
         description: 'Gatekeeper version'
         required: true
-        default: '3.15.0'
+        default: '3.16.0'
         type: string
 
 jobs:
@@ -24,6 +24,7 @@ jobs:
       AZURE_CLIENT_ID: 814e6e97-120c-4534-b8a9-f1645bc99500
       AZURE_TENANT_ID: 72f988bf-86f1-41af-91ab-2d7cd011db47
       AZURE_SUBSCRIPTION_ID: daae1e1a-63dc-454f-825d-b39289070f79
+      AZURE_SP_OBJECT_ID: fd917b28-cdc0-4828-92c9-1ca8203842a3
     runs-on: ubuntu-latest
     timeout-minutes: 30
     environment: azure-test
@@ -38,7 +39,7 @@ jobs:
         with:
           go-version: '1.21'
       - name: Az CLI login
-        uses: azure/login@6b2456866fc08b011acb422a92a4aa20e2c4de32 # v2.1.0
+        uses: azure/login@6c251865b4e6290e7b78be643ea2d005bc51f69a # v2.1.1
         with:
           client-id: ${{ env.AZURE_CLIENT_ID }}
           tenant-id: ${{ env.AZURE_TENANT_ID }}
@@ -60,7 +61,7 @@ jobs:
 
       - name: Run e2e on Azure
         run: |
-          make e2e-aks KUBERNETES_VERSION=${{ inputs.k8s_version }} GATEKEEPER_VERSION=${{ inputs.gatekeeper_version }} TENANT_ID=${{ env.AZURE_TENANT_ID }}
+          make e2e-aks KUBERNETES_VERSION=${{ inputs.k8s_version }} GATEKEEPER_VERSION=${{ inputs.gatekeeper_version }} TENANT_ID=${{ env.AZURE_TENANT_ID }} AZURE_SP_OBJECT_ID=${{ env.AZURE_SP_OBJECT_ID }}
 
       - name: Upload artifacts
         uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
diff --git a/.github/workflows/e2e-k8s.yml b/.github/workflows/e2e-k8s.yml
index 22682e7..4d1e245 100644
--- a/.github/workflows/e2e-k8s.yml
+++ b/.github/workflows/e2e-k8s.yml
@@ -14,7 +14,7 @@ on:
       gatekeeper_version:
         description: 'Gatekeeper version'
         required: true
-        default: '3.15.0'
+        default: '3.16.0'
         type: string
 
 jobs:
diff --git a/pkg/verifier/cosign/cosign_test.go b/pkg/verifier/cosign/cosign_test.go
index eef2f3d..0b6bf26 100644
--- a/pkg/verifier/cosign/cosign_test.go
+++ b/pkg/verifier/cosign/cosign_test.go
@@ -17,12 +17,14 @@ package cosign
 
 import (
 	"context"
+	"crypto"
 	"crypto/ecdh"
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
 	"crypto/rsa"
 	"fmt"
+	"io"
 	"slices"
 	"strings"
 	"testing"
@@ -37,10 +39,26 @@ import (
 	imgspec "github.com/opencontainers/image-spec/specs-go/v1"
 	"github.com/sigstore/cosign/v2/pkg/cosign"
 	"github.com/sigstore/cosign/v2/pkg/oci/static"
+	"github.com/sigstore/rekor/pkg/generated/client"
 	"github.com/sigstore/sigstore/pkg/cryptoutils"
+	"github.com/sigstore/sigstore/pkg/signature"
 )
 
-const ratifySampleImageRef string = "ghcr.io/deislabs/ratify:v1"
+const (
+	ratifySampleImageRef string = "ghcr.io/deislabs/ratify:v1"
+	testIdentity         string = "sozercan@gmail.com"
+	testIssuer           string = "https://github.com/login/oauth"
+)
+
+type mockNoOpVerifier struct{}
+
+func (m *mockNoOpVerifier) PublicKey(_ ...signature.PublicKeyOption) (crypto.PublicKey, error) {
+	return nil, nil
+}
+
+func (m *mockNoOpVerifier) VerifySignature(_, _ io.Reader, _ ...signature.VerifyOption) error {
+	return nil
+}
 
 // TestCreate tests the Create function of the cosign verifier
 func TestCreate(t *testing.T) {
@@ -57,7 +75,7 @@ func TestCreate(t *testing.T) {
 				"trustPolicies": []TrustPolicyConfig{
 					{
 						Name:    "test",
-						Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+						Keyless: KeylessConfig{CertificateIdentity: testIdentity, CertificateOIDCIssuer: testIssuer},
 						Scopes:  []string{"*"},
 					},
 				},
@@ -104,7 +122,7 @@ func TestCreate(t *testing.T) {
 				"trustPolicies": []TrustPolicyConfig{
 					{
 						Name:    "test",
-						Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+						Keyless: KeylessConfig{CertificateIdentity: testIdentity, CertificateOIDCIssuer: testIssuer},
 						Scopes:  []string{"*"},
 					},
 				},
@@ -135,7 +153,7 @@ func TestName(t *testing.T) {
 		"trustPolicies": []TrustPolicyConfig{
 			{
 				Name:    "test",
-				Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+				Keyless: KeylessConfig{CertificateIdentity: testIdentity, CertificateOIDCIssuer: testIssuer},
 				Scopes:  []string{"*"},
 			},
 		},
@@ -159,7 +177,7 @@ func TestType(t *testing.T) {
 		"trustPolicies": []TrustPolicyConfig{
 			{
 				Name:    "test",
-				Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+				Keyless: KeylessConfig{CertificateIdentity: testIdentity, CertificateOIDCIssuer: testIssuer},
 				Scopes:  []string{"*"},
 			},
 		},
@@ -212,7 +230,7 @@ func TestCanVerify(t *testing.T) {
 				"trustPolicies": []TrustPolicyConfig{
 					{
 						Name:    "test",
-						Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+						Keyless: KeylessConfig{CertificateIdentity: testIdentity, CertificateOIDCIssuer: testIssuer},
 						Scopes:  []string{"*"},
 					},
 				},
@@ -238,7 +256,7 @@ func TestGetNestedReferences(t *testing.T) {
 		"trustPolicies": []TrustPolicyConfig{
 			{
 				Name:    "test",
-				Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+				Keyless: KeylessConfig{CertificateIdentity: testIdentity, CertificateOIDCIssuer: testIssuer},
 				Scopes:  []string{"*"},
 			},
 		},
@@ -442,61 +460,24 @@ func TestDecodeASN1Signature(t *testing.T) {
 }
 
 func TestGetKeysMaps_Success(t *testing.T) {
-	trustPolciesConfig := []TrustPolicyConfig{
-		{
-			Name:    "test-policy",
-			Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
-			Scopes:  []string{"ghcr.io/*"},
-		},
-	}
-
-	trustPolicies, err := CreateTrustPolicies(trustPolciesConfig, "test")
-	if err != nil {
-		t.Fatalf("CreateTrustPolicies() error = %v", err)
-	}
-	_, _, err = getKeysMapsDefault(context.Background(), trustPolicies, ratifySampleImageRef, "gatekeeper-system")
+	trustPolicy := &mockTrustPolicy{}
+	_, _, err := getKeyMapOptsDefault(context.Background(), trustPolicy, "gatekeeper-system")
 	if err != nil {
 		t.Errorf("getKeysMaps() error = %v, wantErr %v", err, false)
 	}
 }
 
-func TestGetKeysMaps_FailingTrustPolicies(t *testing.T) {
-	trustPolciesConfig := []TrustPolicyConfig{
-		{
-			Name:    "test-policy",
-			Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
-			Scopes:  []string{"myregistry.io/*"},
-		},
-	}
-
-	trustPolicies, err := CreateTrustPolicies(trustPolciesConfig, "test")
-	if err != nil {
-		t.Fatalf("CreateTrustPolicies() error = %v", err)
-	}
-	_, _, err = getKeysMapsDefault(context.Background(), trustPolicies, ratifySampleImageRef, "gatekeeper-system")
+func TestGetKeysMaps_FailingCosignOpts(t *testing.T) {
+	trustPolicy := &mockTrustPolicy{shouldErrCosignOpts: true}
+	_, _, err := getKeyMapOptsDefault(context.Background(), trustPolicy, "gatekeeper-system")
 	if err == nil {
 		t.Errorf("getKeysMaps() error = %v, wantErr %v", err, true)
 	}
 }
 
 func TestGetKeysMaps_FailingGetKeys(t *testing.T) {
-	trustPolciesConfig := []TrustPolicyConfig{
-		{
-			Name: "test-policy",
-			Keys: []KeyConfig{
-				{
-					Provider: "non-existent",
-				},
-			},
-			Scopes: []string{"*"},
-		},
-	}
-
-	trustPolicies, err := CreateTrustPolicies(trustPolciesConfig, "test")
-	if err != nil {
-		t.Fatalf("CreateTrustPolicies() error = %v", err)
-	}
-	_, _, err = getKeysMapsDefault(context.Background(), trustPolicies, ratifySampleImageRef, "gatekeeper-system")
+	trustPolicy := &mockTrustPolicy{shouldErrKeys: true}
+	_, _, err := getKeyMapOptsDefault(context.Background(), trustPolicy, "gatekeeper-system")
 	if err == nil {
 		t.Errorf("getKeysMaps() error = %v, wantErr %v", err, true)
 	}
@@ -581,6 +562,7 @@ mmBwUAwwW0Uc+Nt3bDOCiB1nUsICv1ry
 		cosignOpts                  cosign.CheckOpts
 		store                       *mocks.MemoryTestStore
 		expectedResultMessagePrefix string
+		defaultCosignOpts           bool
 	}{
 		{
 			name:                        "get keys error",
@@ -677,7 +659,7 @@ mmBwUAwwW0Uc+Nt3bDOCiB1nUsICv1ry
 					blobDigest: validSignatureBlob,
 				},
 			},
-			expectedResultMessagePrefix: "cosign verification failed: failed to process AKV signature: unsupported public key type",
+			expectedResultMessagePrefix: "cosign verification failed: failed to verify with keys: failed to process AKV signature: unsupported public key type",
 		},
 		{
 			name: "invalid RSA key size for AKV",
@@ -708,7 +690,7 @@ mmBwUAwwW0Uc+Nt3bDOCiB1nUsICv1ry
 					blobDigest: validSignatureBlob,
 				},
 			},
-			expectedResultMessagePrefix: "cosign verification failed: failed to process AKV signature: RSA key check: unsupported key size",
+			expectedResultMessagePrefix: "cosign verification failed: failed to verify with keys: failed to process AKV signature: RSA key check: unsupported key size",
 		},
 		{
 			name: "invalid ECDSA curve type for AKV",
@@ -739,7 +721,7 @@ mmBwUAwwW0Uc+Nt3bDOCiB1nUsICv1ry
 					blobDigest: validSignatureBlob,
 				},
 			},
-			expectedResultMessagePrefix: "cosign verification failed: failed to process AKV signature: ECDSA key check: unsupported key curve",
+			expectedResultMessagePrefix: "cosign verification failed: failed to verify with keys: failed to process AKV signature: ECDSA key check: unsupported key curve",
 		},
 		{
 			name: "valid hash: 256 keysize: 2048 RSA key AKV",
@@ -901,22 +883,99 @@ mmBwUAwwW0Uc+Nt3bDOCiB1nUsICv1ry
 			},
 			expectedResultMessagePrefix: "cosign verification success",
 		},
+		{
+			name:              "successful keyless verification",
+			keys:              map[PKKey]keymanagementprovider.PublicKey{},
+			defaultCosignOpts: true,
+			getKeysError:      false,
+			store: &mocks.MemoryTestStore{
+				Manifests: map[digest.Digest]ocispecs.ReferenceManifest{
+					testRefDigest: {
+						MediaType: refDescriptor.MediaType,
+						Blobs: []imgspec.Descriptor{
+							{
+								Digest: digest.NewDigestFromEncoded(digest.SHA256, "d1226e36bc8502978324cb2cb2116c6aa48edb2ea8f15b1c6f6f256ed43388f6"),
+								Annotations: map[string]string{
+									"dev.cosignproject.cosign/signature": "MEUCIFBlKbxxg1Ni++g99jeWO8Of3g5L0Xd+qMzdqCZySQ8DAiEA3lcOJPJ1FQOahtWaRU0hG0XxFEsbcVx6SIyzYQMMR0A=",
+									"dev.sigstore.cosign/bundle":         "{\"SignedEntryTimestamp\":\"MEUCIAIZfWhm9x2F7wil5dkWX+0+njT+FWXFr8AskDkiHpzoAiEApDk9STKcBJTkQ4qy9/8gn6ea2wduh3UjbLRnzZQa9gU=\",\"Payload\":{\"body\":\"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJkMTIyNmUzNmJjODUwMjk3ODMyNGNiMmNiMjExNmM2YWE0OGVkYjJlYThmMTViMWM2ZjZmMjU2ZWQ0MzM4OGY2In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRkJsS2J4eGcxTmkrK2c5OWplV084T2YzZzVMMFhkK3FNemRxQ1p5U1E4REFpRUEzbGNPSlBKMUZRT2FodFdhUlUwaEcwWHhGRXNiY1Z4NlNJeXpZUU1NUjBBPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTnZSRU5EUVdsaFowRjNTVUpCWjBsVlVsWjFTa3A2T1VneWJGUldWMDgyTjFCdWMyZDBUWFJUYld4TmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcE5kMDFxUlRKTlJGVjVUWHBCTUZkb1kwNU5hazEzVFdwRk1rMUVWWHBOZWtFd1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVUzWlV0MU9IQnJOMmN5TDBsU2FGSjVNbEF2TWtoamMxTkNZMWcyUWxwb1QwTkpjMndLU0RBMVFWaHhTelZsUzBKR1R6QmxUU3RvU0hGeGFXbHRZVFJVYm5kNll6RnpUMjkwT0hSVVJuYzVlVVJFYlhod1RrdFBRMEZWVlhkblowWkNUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZNYVZWRUNub3hSRzV2YURsVlRXZHBiMDh4ZEZsdU1IYzFTVUpWZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBsQldVUldVakJTUVZGSUwwSkNXWGRHU1VWVFl6STVObHBZU21wWlZ6VkJXakl4YUdGWGQzVlpNamwwVFVOM1IwTnBjMGRCVVZGQ1p6YzRkd3BCVVVWRlNHMW9NR1JJUW5wUGFUaDJXakpzTUdGSVZtbE1iVTUyWWxNNWMySXlaSEJpYVRsMldWaFdNR0ZFUTBKcFVWbExTM2RaUWtKQlNGZGxVVWxGQ2tGblVqZENTR3RCWkhkQ01VRk9NRGxOUjNKSGVIaEZlVmw0YTJWSVNteHVUbmRMYVZOc05qUXphbmwwTHpSbFMyTnZRWFpMWlRaUFFVRkJRbWhzYVhRS1IweFZRVUZCVVVSQlJWbDNVa0ZKWjA5T2EyUndTSGx1Ykc4eWRFOXZZbkJ1Y2tSWFQwSTJTM2x3Y1d0V2RuUlZiVVpLSzFKVFZVZ3JTREJEU1VWTlNBcDBURFp0Y25nemVUTmxWV3R3ZGpJM2JsRk1VbFJhZDFkeVJuSTROR2QxUXpCNFVYZHdkVmxxVFVGdlIwTkRjVWRUVFRRNVFrRk5SRUV5WjBGTlIxVkRDazFCYTB4eVRuaHJWMlUwVHpGV2JFNDFPRTlqTkcxMlpGQjRjRFJhYUZGMFYwdFNNM0pGUmxCS2FXOXFOMWM1YkV3d1VIYzFiVlp5T1VaQ2VrZzJjMW9LY0dkSmVFRlFhamhKVUZaUFZWVlRVM1JUV0dnM1VsZHFkQ3RKVkVsNVYzQjNTWG8zVUd0MWFVOUZNSEJEUnpaSWRrZERkbXdyWmxScE1FMVFkbkpUVUFwb2NuSmxaV2M5UFFvdExTMHRMVVZPUkNCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2c9PSJ9fX19\",\"integratedTime\":1676524985,\"logIndex\":13452680,\"logID\":\"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\"}}",
+									"dev.sigstore.cosign/certificate":    "-----BEGIN CERTIFICATE-----\nMIICoDCCAiagAwIBAgIURVuJJz9H2lTVWO67PnsgtMtSmlMwCgYIKoZIzj0EAwMw\nNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl\ncm1lZGlhdGUwHhcNMjMwMjE2MDUyMzA0WhcNMjMwMjE2MDUzMzA0WjAAMFkwEwYH\nKoZIzj0CAQYIKoZIzj0DAQcDQgAE7eKu8pk7g2/IRhRy2P/2HcsSBcX6BZhOCIsl\nH05AXqK5eKBFO0eM+hHqqiima4Tnwzc1sOot8tTFw9yDDmxpNKOCAUUwggFBMA4G\nA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQULiUD\nz1Dnoh9UMgioO1tYn0w5IBUwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4Y\nZD8wIAYDVR0RAQH/BBYwFIESc296ZXJjYW5AZ21haWwuY29tMCwGCisGAQQBg78w\nAQEEHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDCBiQYKKwYBBAHWeQIE\nAgR7BHkAdwB1AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABhlit\nGLUAAAQDAEYwRAIgONkdpHynlo2tOobpnrDWOB6KypqkVvtUmFJ+RSUH+H0CIEMH\ntL6mrx3y3eUkpv27nQLRTZwWrFr84guC0xQwpuYjMAoGCCqGSM49BAMDA2gAMGUC\nMAkLrNxkWe4O1VlN58Oc4mvdPxp4ZhQtWKR3rEFPJioj7W9lL0Pw5mVr9FBzH6sZ\npgIxAPj8IPVOUUSStSXh7RWjt+ITIyWpwIz7PkuiOE0pCG6HvGCvl+fTi0MPvrSP\nhrreeg==\n-----END CERTIFICATE-----\n",
+									"dev.sigstore.cosign/chain":          "-----BEGIN CERTIFICATE-----\nMIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMw\nKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y\nMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3Jl\nLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0C\nAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV7\n7LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS\n0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYB\nBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjp\nKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZI\nzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJR\nnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsP\nmygUY7Ii2zbdCdliiow=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMw\nKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y\nMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3Jl\nLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7\nXeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxex\nX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92j\nYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRY\nwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQ\nKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCM\nWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9\nTNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ\n-----END CERTIFICATE-----",
+								},
+							},
+						},
+					},
+				},
+				Subjects: map[digest.Digest]*ocispecs.SubjectDescriptor{
+					subjectDigest: {
+						Descriptor: imgspec.Descriptor{
+							Digest:    digest.NewDigestFromEncoded(digest.SHA256, "623621b56649b5e0c2c7cf3ffd987932f8f9a5a01036e00d6f3ae9480087621c"),
+							MediaType: imgspec.MediaTypeImageManifest,
+						},
+					},
+				},
+				Blobs: map[digest.Digest][]byte{
+					"sha256:d1226e36bc8502978324cb2cb2116c6aa48edb2ea8f15b1c6f6f256ed43388f6": []byte(`{"critical":{"identity":{"docker-reference":"wabbitnetworks.azurecr.io/test/cosign-image"},"image":{"docker-manifest-digest":"sha256:623621b56649b5e0c2c7cf3ffd987932f8f9a5a01036e00d6f3ae9480087621c"},"type":"cosign container image signature"},"optional":null}`),
+				},
+			},
+			expectedResultMessagePrefix: "cosign verification success",
+		},
+		{
+			name:              "failed keyless verification",
+			keys:              map[PKKey]keymanagementprovider.PublicKey{},
+			defaultCosignOpts: true,
+			getKeysError:      false,
+			store: &mocks.MemoryTestStore{
+				Manifests: map[digest.Digest]ocispecs.ReferenceManifest{
+					testRefDigest: {
+						MediaType: refDescriptor.MediaType,
+						Blobs: []imgspec.Descriptor{
+							{
+								Digest: digest.NewDigestFromEncoded(digest.SHA256, "d1226e36bc8502978324cb2cb2116c6aa48edb2ea8f15b1c6f6f256ed43388f6"),
+								Annotations: map[string]string{
+									"dev.cosignproject.cosign/signature": "MEUCIFBlKbxxg1Ni++g99jeWO8Of3g5L0Xd+qMzdqCZySQ8DAiEA3lcOJPJ1FQOahtWaRU0hG0XxFEsbcVx6SIyzYQMMR0A=",
+									"dev.sigstore.cosign/bundle":         "{\"SignedEntryTimestamp\":\"AIZfWhm9x2F7wil5dkWX+0+njT+FWXFr8AskDkiHpzoAiEApDk9STKcBJTkQ4qy9/8gn6ea2wduh3UjbLRnzZQa9gU=\",\"Payload\":{\"body\":\"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJkMTIyNmUzNmJjODUwMjk3ODMyNGNiMmNiMjExNmM2YWE0OGVkYjJlYThmMTViMWM2ZjZmMjU2ZWQ0MzM4OGY2In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRkJsS2J4eGcxTmkrK2c5OWplV084T2YzZzVMMFhkK3FNemRxQ1p5U1E4REFpRUEzbGNPSlBKMUZRT2FodFdhUlUwaEcwWHhGRXNiY1Z4NlNJeXpZUU1NUjBBPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTnZSRU5EUVdsaFowRjNTVUpCWjBsVlVsWjFTa3A2T1VneWJGUldWMDgyTjFCdWMyZDBUWFJUYld4TmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcE5kMDFxUlRKTlJGVjVUWHBCTUZkb1kwNU5hazEzVFdwRk1rMUVWWHBOZWtFd1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVUzWlV0MU9IQnJOMmN5TDBsU2FGSjVNbEF2TWtoamMxTkNZMWcyUWxwb1QwTkpjMndLU0RBMVFWaHhTelZsUzBKR1R6QmxUU3RvU0hGeGFXbHRZVFJVYm5kNll6RnpUMjkwT0hSVVJuYzVlVVJFYlhod1RrdFBRMEZWVlhkblowWkNUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZNYVZWRUNub3hSRzV2YURsVlRXZHBiMDh4ZEZsdU1IYzFTVUpWZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBsQldVUldVakJTUVZGSUwwSkNXWGRHU1VWVFl6STVObHBZU21wWlZ6VkJXakl4YUdGWGQzVlpNamwwVFVOM1IwTnBjMGRCVVZGQ1p6YzRkd3BCVVVWRlNHMW9NR1JJUW5wUGFUaDJXakpzTUdGSVZtbE1iVTUyWWxNNWMySXlaSEJpYVRsMldWaFdNR0ZFUTBKcFVWbExTM2RaUWtKQlNGZGxVVWxGQ2tGblVqZENTR3RCWkhkQ01VRk9NRGxOUjNKSGVIaEZlVmw0YTJWSVNteHVUbmRMYVZOc05qUXphbmwwTHpSbFMyTnZRWFpMWlRaUFFVRkJRbWhzYVhRS1IweFZRVUZCVVVSQlJWbDNVa0ZKWjA5T2EyUndTSGx1Ykc4eWRFOXZZbkJ1Y2tSWFQwSTJTM2x3Y1d0V2RuUlZiVVpLSzFKVFZVZ3JTREJEU1VWTlNBcDBURFp0Y25nemVUTmxWV3R3ZGpJM2JsRk1VbFJhZDFkeVJuSTROR2QxUXpCNFVYZHdkVmxxVFVGdlIwTkRjVWRUVFRRNVFrRk5SRUV5WjBGTlIxVkRDazFCYTB4eVRuaHJWMlUwVHpGV2JFNDFPRTlqTkcxMlpGQjRjRFJhYUZGMFYwdFNNM0pGUmxCS2FXOXFOMWM1YkV3d1VIYzFiVlp5T1VaQ2VrZzJjMW9LY0dkSmVFRlFhamhKVUZaUFZWVlRVM1JUV0dnM1VsZHFkQ3RKVkVsNVYzQjNTWG8zVUd0MWFVOUZNSEJEUnpaSWRrZERkbXdyWmxScE1FMVFkbkpUVUFwb2NuSmxaV2M5UFFvdExTMHRMVVZPUkNCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2c9PSJ9fX19\",\"integratedTime\":1676524985,\"logIndex\":13452680,\"logID\":\"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\"}}",
+									"dev.sigstore.cosign/certificate":    "-----BEGIN CERTIFICATE-----\nMIICoDCCAiagAwIBAgIURVuJJz9H2lTVWO67PnsgtMtSmlMwCgYIKoZIzj0EAwMw\nNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl\ncm1lZGlhdGUwHhcNMjMwMjE2MDUyMzA0WhcNMjMwMjE2MDUzMzA0WjAAMFkwEwYH\nKoZIzj0CAQYIKoZIzj0DAQcDQgAE7eKu8pk7g2/IRhRy2P/2HcsSBcX6BZhOCIsl\nH05AXqK5eKBFO0eM+hHqqiima4Tnwzc1sOot8tTFw9yDDmxpNKOCAUUwggFBMA4G\nA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQULiUD\nz1Dnoh9UMgioO1tYn0w5IBUwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4Y\nZD8wIAYDVR0RAQH/BBYwFIESc296ZXJjYW5AZ21haWwuY29tMCwGCisGAQQBg78w\nAQEEHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDCBiQYKKwYBBAHWeQIE\nAgR7BHkAdwB1AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABhlit\nGLUAAAQDAEYwRAIgONkdpHynlo2tOobpnrDWOB6KypqkVvtUmFJ+RSUH+H0CIEMH\ntL6mrx3y3eUkpv27nQLRTZwWrFr84guC0xQwpuYjMAoGCCqGSM49BAMDA2gAMGUC\nMAkLrNxkWe4O1VlN58Oc4mvdPxp4ZhQtWKR3rEFPJioj7W9lL0Pw5mVr9FBzH6sZ\npgIxAPj8IPVOUUSStSXh7RWjt+ITIyWpwIz7PkuiOE0pCG6HvGCvl+fTi0MPvrSP\nhrreeg==\n-----END CERTIFICATE-----\n",
+									"dev.sigstore.cosign/chain":          "-----BEGIN CERTIFICATE-----\nMIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMw\nKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y\nMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3Jl\nLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0C\nAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV7\n7LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS\n0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYB\nBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjp\nKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZI\nzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJR\nnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsP\nmygUY7Ii2zbdCdliiow=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMw\nKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y\nMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3Jl\nLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7\nXeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxex\nX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92j\nYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRY\nwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQ\nKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCM\nWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9\nTNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ\n-----END CERTIFICATE-----",
+								},
+							},
+						},
+					},
+				},
+				Subjects: map[digest.Digest]*ocispecs.SubjectDescriptor{
+					subjectDigest: {
+						Descriptor: imgspec.Descriptor{
+							Digest:    digest.NewDigestFromEncoded(digest.SHA256, "623621b56649b5e0c2c7cf3ffd987932f8f9a5a01036e00d6f3ae9480087621c"),
+							MediaType: imgspec.MediaTypeImageManifest,
+						},
+					},
+				},
+				Blobs: map[digest.Digest][]byte{
+					"sha256:d1226e36bc8502978324cb2cb2116c6aa48edb2ea8f15b1c6f6f256ed43388f6": []byte(`{"critical":{"identity":{"docker-reference":"wabbitnetworks.azurecr.io/test/cosign-image"},"image":{"docker-manifest-digest":"sha256:623621b56649b5e0c2c7cf3ffd987932f8f9a5a01036e00d6f3ae9480087621c"},"type":"cosign container image signature"},"optional":null}`),
+				},
+			},
+			expectedResultMessagePrefix: "cosign verification failed",
+		},
 	}
 
 	for _, tt := range tc {
 		t.Run(tt.name, func(t *testing.T) {
-			getKeysMaps = func(_ context.Context, _ *TrustPolicies, _ string, _ string) (map[PKKey]keymanagementprovider.PublicKey, cosign.CheckOpts, error) {
+			getKeyMapOpts = func(ctx context.Context, trustPolicy TrustPolicy, _ string) (map[PKKey]keymanagementprovider.PublicKey, cosign.CheckOpts, error) {
+				co := tt.cosignOpts
 				if tt.getKeysError {
 					return nil, cosign.CheckOpts{}, fmt.Errorf("error")
 				}
 
-				return tt.keys, tt.cosignOpts, nil
+				if tt.defaultCosignOpts {
+					co, _ = trustPolicy.GetCosignOpts(ctx)
+				}
+
+				return tt.keys, co, nil
 			}
 			verifierFactory := cosignVerifierFactory{}
 			trustPoliciesConfig := []TrustPolicyConfig{
 				{
 					Name:    "test-policy",
-					Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+					Keyless: KeylessConfig{CertificateIdentity: testIdentity, CertificateOIDCIssuer: testIssuer},
 					Scopes:  []string{"*"},
 				},
 			}
@@ -937,3 +996,42 @@ mmBwUAwwW0Uc+Nt3bDOCiB1nUsICv1ry
 		})
 	}
 }
+
+// TestVerificationMessage tests the verificationMessage function
+func TestVerificationMessage(t *testing.T) {
+	tc := []struct {
+		name             string
+		expectedMessages []string
+		bundleVerified   bool
+		checkOpts        cosign.CheckOpts
+	}{
+		{
+			name:             "keyed, offline bundle, claims with annotations",
+			expectedMessages: []string{annotationMessage, claimsMessage, offlineBundleMessage, sigVerifierMessage},
+			bundleVerified:   true,
+			checkOpts: cosign.CheckOpts{
+				ClaimVerifier: cosign.SimpleClaimVerifier,
+				Annotations: map[string]interface{}{
+					"test": "test",
+				},
+				SigVerifier: &mockNoOpVerifier{},
+			},
+		},
+		{
+			name:             "keyless, rekor, fulcio",
+			expectedMessages: []string{rekorClaimsMessage, rekorSigMessage, certVerifierMessage},
+			bundleVerified:   false,
+			checkOpts: cosign.CheckOpts{
+				RekorClient: &client.Rekor{},
+			},
+		},
+	}
+	for i, tt := range tc {
+		t.Run(tt.name, func(t *testing.T) {
+			result := verificationPerformedMessage(tt.bundleVerified, &tc[i].checkOpts)
+			if !slices.Equal(result, tt.expectedMessages) {
+				t.Errorf("verificationMessage() = %v, want %v", result, tt.expectedMessages)
+			}
+		})
+	}
+}
diff --git a/pkg/verifier/cosign/trustpolicies_test.go b/pkg/verifier/cosign/trustpolicies_test.go
index cdea65b..2d7d292 100644
--- a/pkg/verifier/cosign/trustpolicies_test.go
+++ b/pkg/verifier/cosign/trustpolicies_test.go
@@ -32,7 +32,7 @@ func TestCreateTrustPolicies(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: false,
@@ -53,12 +53,12 @@ func TestCreateTrustPolicies(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v2"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: false,
@@ -69,12 +69,12 @@ func TestCreateTrustPolicies(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -85,12 +85,12 @@ func TestCreateTrustPolicies(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -100,12 +100,12 @@ func TestCreateTrustPolicies(t *testing.T) {
 			policyConfigs: []TrustPolicyConfig{
 				{
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -136,12 +136,12 @@ func TestGetScopedPolicy(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v2"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			reference:      "ghcr.io/deislabs/ratify:v1",
@@ -154,12 +154,12 @@ func TestGetScopedPolicy(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/deislabs/ratify2:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			reference:      "ghcr.io/deislabs/ratify:v1",
@@ -172,12 +172,12 @@ func TestGetScopedPolicy(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/deislabs/ratify2:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			reference:      "ghcr.io/deislabs/ratify3:v1",
@@ -190,12 +190,12 @@ func TestGetScopedPolicy(t *testing.T) {
 				{
 					Name:    "global",
 					Scopes:  []string{"*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/deislabs/ratify2:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			reference:      "ghcr.io/deislabs/ratify3:v1",
@@ -234,7 +234,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: false,
@@ -245,7 +245,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1", "ghcr.io/deislabs/ratify:v2"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: false,
@@ -256,7 +256,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: false,
@@ -267,7 +267,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: false,
@@ -278,7 +278,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: false,
@@ -289,7 +289,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"*", "somescope"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -300,7 +300,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1", "ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -311,12 +311,12 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -327,12 +327,12 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -343,7 +343,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:*", "ghcr.io/deislabs/ratify:*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -354,7 +354,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"*.azurecr.io"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -365,7 +365,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/*/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -376,7 +376,7 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/*", "ghcr.io/deislabs/*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -387,12 +387,12 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/test/*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: false,
@@ -403,12 +403,12 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
@@ -419,12 +419,12 @@ func TestValidateScopes(t *testing.T) {
 				{
 					Name:    "test",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:v1"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 				{
 					Name:    "test-2",
 					Scopes:  []string{"ghcr.io/deislabs/ratify:*"},
-					Keyless: KeylessConfig{RekorURL: "https://rekor.sigstore.dev"},
+					Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 				},
 			},
 			wantErr: true,
diff --git a/pkg/verifier/cosign/trustpolicy_test.go b/pkg/verifier/cosign/trustpolicy_test.go
index c8d5964..c55a91d 100644
--- a/pkg/verifier/cosign/trustpolicy_test.go
+++ b/pkg/verifier/cosign/trustpolicy_test.go
@@ -19,12 +19,45 @@ import (
 	"context"
 	"crypto"
 	"crypto/ecdsa"
+	"fmt"
 	"testing"
 
 	ctxUtils "github.com/deislabs/ratify/internal/context"
 	"github.com/deislabs/ratify/pkg/keymanagementprovider"
+	"github.com/sigstore/cosign/v2/pkg/cosign"
 )
 
+type mockTrustPolicy struct {
+	name                string
+	scopes              []string
+	keysMap             map[PKKey]keymanagementprovider.PublicKey
+	shouldErrKeys       bool
+	shouldErrCosignOpts bool
+}
+
+func (m *mockTrustPolicy) GetName() string {
+	return m.name
+}
+
+func (m *mockTrustPolicy) GetScopes() []string {
+	return m.scopes
+}
+
+func (m *mockTrustPolicy) GetKeys(_ context.Context, _ string) (map[PKKey]keymanagementprovider.PublicKey, error) {
+	if m.shouldErrKeys {
+		return nil, fmt.Errorf("error getting keys")
+	}
+	return m.keysMap, nil
+}
+
+func (m *mockTrustPolicy) GetCosignOpts(_ context.Context) (cosign.CheckOpts, error) {
+	if m.shouldErrCosignOpts {
+		return cosign.CheckOpts{}, fmt.Errorf("error getting cosign opts")
+	}
+
+	return cosign.CheckOpts{}, nil
+}
+
 func TestCreateTrustPolicy(t *testing.T) {
 	tc := []struct {
 		name    string
@@ -68,7 +101,8 @@ func TestCreateTrustPolicy(t *testing.T) {
 				Name:   "test",
 				Scopes: []string{"*"},
 				Keyless: KeylessConfig{
-					RekorURL: DefaultRekorURL,
+					CertificateIdentity:   "test-identity",
+					CertificateOIDCIssuer: "https://test-issuer.com",
 				},
 			},
 			wantErr: false,
@@ -80,7 +114,8 @@ func TestCreateTrustPolicy(t *testing.T) {
 				Name:    "test",
 				Scopes:  []string{"*"},
 				Keyless: KeylessConfig{
-					RekorURL: DefaultRekorURL,
+					CertificateIdentity:   "test-identity",
+					CertificateOIDCIssuer: "https://test-issuer.com",
 				},
 			},
 			wantErr: true,
@@ -101,7 +136,7 @@ func TestGetName(t *testing.T) {
 	trustPolicyConfig := TrustPolicyConfig{
 		Name:    "test",
 		Scopes:  []string{"*"},
-		Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+		Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 	}
 	trustPolicy, err := CreateTrustPolicy(trustPolicyConfig, "test-verifier")
 	if err != nil {
@@ -117,7 +152,7 @@ func TestGetScopes(t *testing.T) {
 	trustPolicyConfig := TrustPolicyConfig{
 		Name:    "test",
 		Scopes:  []string{"*"},
-		Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+		Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 	}
 	trustPolicy, err := CreateTrustPolicy(trustPolicyConfig, "test-verifier")
 	if err != nil {
@@ -210,53 +245,65 @@ func TestValidate(t *testing.T) {
 		wantErr      bool
 	}{
 		{
-			name:         "no name",
+			name:         "no version",
 			policyConfig: TrustPolicyConfig{},
 			wantErr:      true,
 		},
+		{
+			name: "no name",
+			policyConfig: TrustPolicyConfig{
+				Version: "1.0.0",
+			},
+			wantErr: true,
+		},
 		{
 			name: "no scopes",
 			policyConfig: TrustPolicyConfig{
-				Name: "test",
+				Version: "1.0.0",
+				Name:    "test",
 			},
 			wantErr: true,
 		},
 		{
 			name: "no keys or keyless defined",
 			policyConfig: TrustPolicyConfig{
-				Name:   "test",
-				Scopes: []string{"*"},
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
 			},
 			wantErr: true,
 		},
 		{
 			name: "keys and keyless defined",
 			policyConfig: TrustPolicyConfig{
-				Name:   "test",
-				Scopes: []string{"*"},
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
 				Keys: []KeyConfig{
 					{
 						Provider: "kmp",
 					},
 				},
-				Keyless: KeylessConfig{RekorURL: DefaultRekorURL},
+				Keyless: KeylessConfig{CertificateIdentity: "test-identity", CertificateOIDCIssuer: "https://test-issuer.com"},
 			},
 			wantErr: true,
 		},
 		{
 			name: "key provider and key path not defined",
 			policyConfig: TrustPolicyConfig{
-				Name:   "test",
-				Scopes: []string{"*"},
-				Keys:   []KeyConfig{{}},
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
+				Keys:    []KeyConfig{{}},
 			},
 			wantErr: true,
 		},
 		{
 			name: "key provider and key path both defined",
 			policyConfig: TrustPolicyConfig{
-				Name:   "test",
-				Scopes: []string{"*"},
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
 				Keys: []KeyConfig{
 					{
 						Provider: "kmp",
@@ -269,8 +316,9 @@ func TestValidate(t *testing.T) {
 		{
 			name: "key provider not defined but name defined",
 			policyConfig: TrustPolicyConfig{
-				Name:   "test",
-				Scopes: []string{"*"},
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
 				Keys: []KeyConfig{
 					{
 						Name: "key name",
@@ -282,8 +330,9 @@ func TestValidate(t *testing.T) {
 		{
 			name: "key provider name not defined but version defined",
 			policyConfig: TrustPolicyConfig{
-				Name:   "test",
-				Scopes: []string{"*"},
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
 				Keys: []KeyConfig{
 					{
 						Provider: "kmp",
@@ -309,6 +358,66 @@ func TestValidate(t *testing.T) {
 			},
 			wantErr: false,
 		},
+		{
+			name: "keyless but no certificate identity specified",
+			policyConfig: TrustPolicyConfig{
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
+				Keyless: KeylessConfig{CertificateOIDCIssuer: "test"},
+			},
+			wantErr: true,
+		},
+		{
+			name: "keyless but both certificate identity and expression specified",
+			policyConfig: TrustPolicyConfig{
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
+				Keyless: KeylessConfig{CertificateIdentity: "test", CertificateIdentityRegExp: "test"},
+			},
+			wantErr: true,
+		},
+		{
+			name: "keyless but no certificate oidc issuer specified",
+			policyConfig: TrustPolicyConfig{
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
+				Keyless: KeylessConfig{CertificateIdentity: "test"},
+			},
+			wantErr: true,
+		},
+		{
+			name: "keyless but both certificate oidc issuer and expression specified",
+			policyConfig: TrustPolicyConfig{
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
+				Keyless: KeylessConfig{CertificateIdentity: "test", CertificateOIDCIssuer: "test", CertificateOIDCIssuerRegExp: "test"},
+			},
+			wantErr: true,
+		},
+		{
+			name: "keyless but both certificate identity and expression specified",
+			policyConfig: TrustPolicyConfig{
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
+				Keyless: KeylessConfig{CertificateOIDCIssuer: "test", CertificateIdentity: "test", CertificateIdentityRegExp: "test"},
+			},
+			wantErr: true,
+		},
+		{
+			name: "valid keyless",
+			policyConfig: TrustPolicyConfig{
+				Version: "1.0.0",
+				Name:    "test",
+				Scopes:  []string{"*"},
+				Keyless: KeylessConfig{CertificateIdentity: "test", CertificateOIDCIssuer: "test"},
+			},
+			wantErr: false,
+		},
 	}
 
 	for _, tt := range tc {
diff --git a/scripts/azure-ci-test.sh b/scripts/azure-ci-test.sh
index 8f1ca35..f0e67ed 100755
--- a/scripts/azure-ci-test.sh
+++ b/scripts/azure-ci-test.sh
@@ -28,10 +28,11 @@ export KEYVAULT_NAME="${KEYVAULT_NAME:-ratify-akv-${SUFFIX}}"
 export USER_ASSIGNED_IDENTITY_NAME="${USER_ASSIGNED_IDENTITY_NAME:-ratify-e2e-identity-${SUFFIX}}"
 export LOCATION="eastus"
 export KUBERNETES_VERSION=${1:-1.29.2}
-GATEKEEPER_VERSION=${2:-3.15.0}
+GATEKEEPER_VERSION=${2:-3.16.0}
 TENANT_ID=$3
 export RATIFY_NAMESPACE=${4:-gatekeeper-system}
 CERT_DIR=${5:-"~/ratify/certs"}
+export AZURE_SP_OBJECT_ID=$6
 export NOTATION_PEM_NAME="notation"
 export NOTATION_CHAIN_PEM_NAME="notationchain"
 export KEYVAULT_KEY_NAME="test-key"
@@ -78,8 +79,8 @@ deploy_ratify() {
 
   kubectl delete verifiers.config.ratify.deislabs.io/verifier-cosign
 
-  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
+  kubectl apply -f https://ratify-project.github.io/ratify/library/default/template.yaml
+  kubectl apply -f https://ratify-project.github.io/ratify/library/default/samples/constraint.yaml
 }
 
 upload_cert_to_akv() {
@@ -126,6 +127,12 @@ save_logs() {
 cleanup() {
   save_logs || true
 
+  echo "Delete key vault"
+  az keyvault delete --name "${KEYVAULT_NAME}" --resource-group "${GROUP_NAME}" || true
+
+  echo "Purge key vault"
+  az keyvault purge --name "${KEYVAULT_NAME}" --no-wait || true
+
   echo "Deleting group"
   az group delete --name "${GROUP_NAME}" --yes --no-wait || true
 }
diff --git a/test/bats/azure-test.bats b/test/bats/azure-test.bats
index bde2056..a30556d 100644
--- a/test/bats/azure-test.bats
+++ b/test/bats/azure-test.bats
@@ -32,7 +32,7 @@ SLEEP_TIME=1
 
     # enable dynamic plugins
     helm upgrade --atomic --namespace gatekeeper-system --reuse-values --set featureFlags.RATIFY_EXPERIMENTAL_DYNAMIC_PLUGINS=true ratify ./charts/ratify
-    sleep 5
+    sleep 30
     latestpod=$(kubectl -n gatekeeper-system get pod -l=app.kubernetes.io/name=ratify --sort-by=.metadata.creationTimestamp -o=name | tail -n 1)
 
     run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_dynamic.yaml
@@ -60,7 +60,7 @@ SLEEP_TIME=1
     assert_success
 
     # verify that the image can be run with a root cert, root verification cert should have been configured on deployment
-    run kubectl run demo-leaf --namespace default --image=${TEST_REGISTRY}/notation:leafSigned
+    wait_for_process 20 10 'kubectl run demo-leaf --namespace default --image=${TEST_REGISTRY}/notation:leafSigned'
     assert_success
 
     # add the leaf certificate as an inline certificate store
@@ -93,7 +93,7 @@ SLEEP_TIME=1
     run kubectl apply -f ./library/multi-tenancy-validation/samples/constraint.yaml
     assert_success
     sleep 5
-    run kubectl run demo --namespace default --image=${TEST_REGISTRY}/notation:signed
+    wait_for_process 20 10 'kubectl run demo --namespace default --image=${TEST_REGISTRY}/notation:signed'
     assert_success
     run kubectl run demo1 --namespace default --image=${TEST_REGISTRY}/notation:unsigned
     assert_failure
@@ -116,7 +116,7 @@ SLEEP_TIME=1
     assert_success
     sleep 5
 
-    run kubectl run cosign-demo --namespace default --image=${TEST_REGISTRY}/cosign:signed-key
+    wait_for_process 20 10 'kubectl run cosign-demo --namespace default --image=${TEST_REGISTRY}/cosign:signed-key'
     assert_success
     run kubectl run cosign-demo2 --namespace default --image=${TEST_REGISTRY}/cosign:unsigned
     assert_failure
@@ -145,7 +145,7 @@ SLEEP_TIME=1
     run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_complete_licensechecker.yaml
     # wait for the httpserver cache to be invalidated
     sleep 15
-    run kubectl run license-checker2 --namespace default --image=${TEST_REGISTRY}/licensechecker:v0
+    wait_for_process 20 10 'kubectl run license-checker2 --namespace default --image=${TEST_REGISTRY}/licensechecker:v0'
     assert_success
 }
 
@@ -165,7 +165,7 @@ SLEEP_TIME=1
 
     run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_sbom.yaml
     sleep 5
-    run kubectl run sbom --namespace default --image=${TEST_REGISTRY}/sbom:v0
+    wait_for_process 20 10 'kubectl run sbom --namespace default --image=${TEST_REGISTRY}/sbom:v0'
     assert_success
 
     run kubectl delete verifiers.config.ratify.deislabs.io/verifier-sbom
@@ -196,7 +196,7 @@ SLEEP_TIME=1
     run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_schemavalidator.yaml
     sleep 5
 
-    run kubectl run schemavalidator --namespace default --image=${TEST_REGISTRY}/schemavalidator:v0
+    wait_for_process 20 10 'kubectl run schemavalidator --namespace default --image=${TEST_REGISTRY}/schemavalidator:v0'
     assert_success
 
     run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_schemavalidator_bad.yaml
@@ -230,7 +230,7 @@ SLEEP_TIME=1
     run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_schemavalidator.yaml
     sleep 5
 
-    run kubectl run all-in-one --namespace default --image=${TEST_REGISTRY}/all:v0
+    wait_for_process 20 10 'kubectl run all-in-one --namespace default --image=${TEST_REGISTRY}/all:v0'
     assert_success
 }
 
@@ -256,7 +256,7 @@ SLEEP_TIME=1
 
     # wait for the httpserver cache to be invalidated
     sleep 15
-    run kubectl run crdtest --namespace default --image=${TEST_REGISTRY}/notation:signed
+    wait_for_process 20 10 'kubectl run crdtest --namespace default --image=${TEST_REGISTRY}/notation:signed'
     assert_success
 }
 
@@ -268,7 +268,7 @@ SLEEP_TIME=1
     run kubectl apply -f ./library/multi-tenancy-validation/samples/constraint.yaml
     assert_success
     sleep 5
-    run kubectl run demo2 --image=${TEST_REGISTRY}/notation:signed
+    wait_for_process 20 10 'kubectl run demo2 --image=${TEST_REGISTRY}/notation:signed'
     assert_success
 
     run kubectl get configmaps ratify-configuration --namespace=gatekeeper-system -o yaml >currentConfig.yaml
@@ -313,7 +313,7 @@ SLEEP_TIME=1
     run kubectl apply -f ./library/multi-tenancy-validation/samples/constraint.yaml
     assert_success
     sleep 5
-    run kubectl run mutate-demo --namespace default --image=${TEST_REGISTRY}/notation:signed
+    wait_for_process 20 10 'kubectl run mutate-demo --namespace default --image=${TEST_REGISTRY}/notation:signed'
     assert_success
     result=$(kubectl get pod mutate-demo --namespace default -o json | jq -r ".spec.containers[0].image" | grep @sha)
     assert_mutate_success
diff --git a/test/bats/base-test.bats b/test/bats/base-test.bats
index 11d6ed5..ca54ef3 100644
--- a/test/bats/base-test.bats
+++ b/test/bats/base-test.bats
@@ -170,7 +170,7 @@ RATIFY_NAMESPACE=gatekeeper-system
     assert_failure
 }
 
-@test "cosign legacy test" {
+@test "cosign legacy keyed test" {
     teardown() {
         echo "cleaning up"
         wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete pod cosign-demo-key --namespace default --force --ignore-not-found=true'
@@ -203,8 +203,7 @@ RATIFY_NAMESPACE=gatekeeper-system
         wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl replace -f ./config/samples/clustered/store/config_v1beta1_store_oras_http.yaml'
     }
 
-    # use imperative command to guarantee useHttp is updated
-    run kubectl replace -f ./config/samples/clustered/verifier/config_v1beta1_verifier_cosign_keyless.yaml
+    run kubectl replace -f ./test/bats/tests/config/config_v1beta1_verifier_cosign_keyless.yaml
     sleep 5
 
     run kubectl replace -f ./config/samples/clustered/store/config_v1beta1_store_oras.yaml
@@ -213,6 +212,23 @@ RATIFY_NAMESPACE=gatekeeper-system
     wait_for_process 20 10 'kubectl run cosign-demo-keyless --namespace default --image=wabbitnetworks.azurecr.io/test/cosign-image:signed-keyless'
 }
 
+@test "cosign legacy keyless test" {
+    teardown() {
+        echo "cleaning up"
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete pod cosign-demo-keyless --namespace default --force --ignore-not-found=true'
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl replace -f ./config/samples/clustered/verifier/config_v1beta1_verifier_cosign.yaml'
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl replace -f ./config/samples/clustered/store/config_v1beta1_store_oras_http.yaml'
+    }
+
+    # use imperative command to guarantee useHttp is updated
+    run kubectl replace -f ./config/samples/clustered/verifier/config_v1beta1_verifier_cosign_keyless_legacy.yaml
+    sleep 5
+
+    run kubectl replace -f ./config/samples/clustered/store/config_v1beta1_store_oras.yaml
+    sleep 5
+
+    wait_for_process 20 10 'kubectl run cosign-demo-keyless --namespace default --image=wabbitnetworks.azurecr.io/test/cosign-image:signed-keyless'
+}
 @test "validate crd add, replace and delete" {
     teardown() {
         echo "cleaning up"
@@ -239,34 +255,6 @@ RATIFY_NAMESPACE=gatekeeper-system
     assert_success
 }
 
-@test "verifier crd status check" {
-    teardown() {
-        echo "cleaning up"
-        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete verifiers.config.ratify.deislabs.io/verifier-license-checker'
-    }
-
-    # apply a valid verifier, validate status property shows success
-    run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_complete_licensechecker.yaml
-    assert_success
-    run bash -c "kubectl describe verifiers.config.ratify.deislabs.io/verifier-license-checker -n ${RATIFY_NAMESPACE} | grep 'Issuccess:  true'"
-    assert_success
-
-    # apply a invalid verifier CR, validate status with error
-    sed 's/licensechecker/invalidlicensechecker/' ./config/samples/clustered/verifier/config_v1beta1_verifier_complete_licensechecker.yaml >invalidVerifier.yaml
-    run kubectl apply -f invalidVerifier.yaml
-    assert_success
-    run bash -c "kubectl describe verifiers.config.ratify.deislabs.io/verifier-license-checker -n ${RATIFY_NAMESPACE} | grep 'Brieferror:  Original Error:'"
-    assert_success
-
-    # apply a valid verifier, validate status property shows success
-    run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_complete_licensechecker.yaml
-    assert_success
-    run bash -c "kubectl describe verifiers.config.ratify.deislabs.io/verifier-license-checker -n ${RATIFY_NAMESPACE} | grep 'Issuccess:  true'"
-    assert_success
-    run bash -c "kubectl describe verifiers.config.ratify.deislabs.io/verifier-license-checker -n ${RATIFY_NAMESPACE} | grep 'Brieferror:  Original Error:'"
-    assert_failure
-}
-
 @test "store crd status check" {
     teardown() {
         echo "cleaning up"
diff --git a/test/bats/plugin-test.bats b/test/bats/plugin-test.bats
index 389d802..3d37bbd 100644
--- a/test/bats/plugin-test.bats
+++ b/test/bats/plugin-test.bats
@@ -18,6 +18,7 @@ load helpers
 BATS_TESTS_DIR=${BATS_TESTS_DIR:-test/bats/tests}
 WAIT_TIME=60
 SLEEP_TIME=1
+RATIFY_NAMESPACE=gatekeeper-system
 
 @test "helm genCert test" {
     # tls cert provided
@@ -295,6 +296,34 @@ SLEEP_TIME=1
     assert_success
 }
 
+@test "verifier crd status check" {
+    teardown() {
+        echo "cleaning up"
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete verifiers.config.ratify.deislabs.io/verifier-license-checker'
+    }
+
+    # apply a valid verifier, validate status property shows success
+    run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_complete_licensechecker.yaml
+    assert_success
+    run bash -c "kubectl describe verifiers.config.ratify.deislabs.io/verifier-license-checker -n ${RATIFY_NAMESPACE} | grep 'Issuccess:  true'"
+    assert_success
+
+    # apply a invalid verifier CR, validate status with error
+    sed 's/licensechecker/invalidlicensechecker/' ./config/samples/clustered/verifier/config_v1beta1_verifier_complete_licensechecker.yaml >invalidVerifier.yaml
+    run kubectl apply -f invalidVerifier.yaml
+    assert_success
+    run bash -c "kubectl describe verifiers.config.ratify.deislabs.io/verifier-license-checker -n ${RATIFY_NAMESPACE} | grep 'Brieferror:  Original Error:'"
+    assert_success
+
+    # apply a valid verifier, validate status property shows success
+    run kubectl apply -f ./config/samples/clustered/verifier/config_v1beta1_verifier_complete_licensechecker.yaml
+    assert_success
+    run bash -c "kubectl describe verifiers.config.ratify.deislabs.io/verifier-license-checker -n ${RATIFY_NAMESPACE} | grep 'Issuccess:  true'"
+    assert_success
+    run bash -c "kubectl describe verifiers.config.ratify.deislabs.io/verifier-license-checker -n ${RATIFY_NAMESPACE} | grep 'Brieferror:  Original Error:'"
+    assert_failure
+}
+
 @test "dynamic plugins disabled test" {
     teardown() {
         echo "cleaning up"
diff --git a/test/bats/tests/config/config_v1beta1_verifier_cosign_akv.yaml b/test/bats/tests/config/config_v1beta1_verifier_cosign_akv.yaml
index a2ca0bd..69fb996 100644
--- a/test/bats/tests/config/config_v1beta1_verifier_cosign_akv.yaml
+++ b/test/bats/tests/config/config_v1beta1_verifier_cosign_akv.yaml
@@ -15,4 +15,5 @@ spec:
         scopes:
           - "*"
         keys:
-          - provider: kmprovider-akv
\ No newline at end of file
+          - provider: kmprovider-akv
+        tLogVerify: false
\ No newline at end of file
diff --git a/test/bats/tests/config/config_v1beta1_verifier_cosign_keyless.yaml b/test/bats/tests/config/config_v1beta1_verifier_cosign_keyless.yaml
new file mode 100644
index 0000000..6e5d134
--- /dev/null
+++ b/test/bats/tests/config/config_v1beta1_verifier_cosign_keyless.yaml
@@ -0,0 +1,15 @@
+apiVersion: config.ratify.deislabs.io/v1beta1
+kind: Verifier
+metadata:
+  name: verifier-cosign
+spec:
+  name: cosign
+  artifactTypes: application/vnd.dev.cosign.artifact.sig.v1+json
+  parameters:
+    trustPolicies:
+      - name: default
+        scopes:
+          - '*'
+        keyless:
+          certificateIdentity: sozercan@gmail.com
+          certificateOIDCIssuer: https://github.com/login/oauth
\ No newline at end of file