Repository: ratify-project/ratify
Pull request #1780 (2024-09-08 08:35:44)

chore: automated PR to main 2024-09-08
Automated Pull Request to main branch


Patch:
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 74475b6..a5bc4d3 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -30,7 +30,7 @@ RUN curl -Lo bats.tar.gz https://github.com/bats-core/bats-core/archive/v${BATS_
   && bash ./bats-core-${BATS_VERSION}/install.sh /usr/local \
   && rm -rf bats.tar.gz ./bats-core-${BATS_VERSION}
 
-ARG NOTATION_VERSION="1.0.0-rc.1"
+ARG NOTATION_VERSION="1.2.0"
 RUN curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v${NOTATION_VERSION}/notation_${NOTATION_VERSION}_linux_amd64.tar.gz \
   && tar -zxf notation.tar.gz \
   && mv ./notation /usr/local/bin/notation \
diff --git a/.github/licenserc.yml b/.github/licenserc.yml
index c976b79..c7ae27c 100644
--- a/.github/licenserc.yml
+++ b/.github/licenserc.yml
@@ -29,7 +29,7 @@ header:
       limitations under the License.
 
   paths-ignore:
-    - "**/*.{md,svg,yaml,crt,json,pub,yml,pb.go,proto}"
+    - "**/*.{md,svg,yaml,crt,cer,json,pub,yml,pb.go,proto}"
     - "CODEOWNERS"
     - "PROJECT"
     - "NOTICE"
diff --git a/Makefile b/Makefile
index e42a9d9..f6895c9 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@ KIND_KUBERNETES_VERSION ?= 1.29.2
 GATEKEEPER_VERSION ?= 3.16.0
 DAPR_VERSION ?= 1.12.5
 COSIGN_VERSION ?= 2.2.3
-NOTATION_VERSION ?= 1.1.0
+NOTATION_VERSION ?= 1.2.0
 ORAS_VERSION ?= 1.1.0
 
 HELM_VERSION ?= 3.14.2
@@ -56,6 +56,8 @@ TRIVY_VERSION ?= 0.49.1
 GATEKEEPER_NAMESPACE = gatekeeper-system
 RATIFY_NAME = ratify
 
+TIMESTAMP_URL = http://timestamp.digicert.com
+
 # Local Registry Setup
 LOCAL_REGISTRY_IMAGE ?= ghcr.io/project-zot/zot-linux-amd64:v2.0.2
 TEST_REGISTRY = localhost:5000
@@ -98,6 +100,7 @@ install:
 ratify-config:
 	cp ./test/bats/tests/config/* ${INSTALL_DIR}
 	cp ./test/bats/tests/certificates/wabbit-networks.io.crt ${INSTALL_DIR}/ratify-certs/notation/wabbit-networks.io.crt
+	cp ./test/bats/tests/certificates/tsarootca.cer ${INSTALL_DIR}/ratify-certs/notation/tsarootca.cer
 	cp ./test/bats/tests/certificates/cosign.pub ${INSTALL_DIR}/ratify-certs/cosign/cosign.pub
 	cp -r ./test/bats/tests/schemas/ ${INSTALL_DIR}
 	
@@ -295,10 +298,16 @@ e2e-notation-setup:
 	${GITHUB_WORKSPACE}/bin/oras cp --from-oci-layout .staging/notation/notation.tar:v0 ${TEST_REGISTRY}/notation:unsigned
 	rm .staging/notation/notation.tar
 
+	printf 'FROM ${ALPINE_IMAGE}\nCMD ["echo", "notation tsa signed image"]' > .staging/notation/Dockerfile
+	docker buildx create --use
+	docker buildx build --output type=oci,dest=.staging/notation/notation.tar -t notation:v0 .staging/notation
+	${GITHUB_WORKSPACE}/bin/oras cp --from-oci-layout .staging/notation/notation.tar:v0 ${TEST_REGISTRY}/notation:tsa
+	rm .staging/notation/notation.tar
+	
 	rm -rf ~/.config/notation
 	.staging/notation/notation cert generate-test --default "ratify-bats-test"
-
 	NOTATION_EXPERIMENTAL=1 .staging/notation/notation sign --allow-referrers-api -u ${TEST_REGISTRY_USERNAME} -p ${TEST_REGISTRY_PASSWORD} ${TEST_REGISTRY}/notation@`${GITHUB_WORKSPACE}/bin/oras manifest fetch ${TEST_REGISTRY}/notation:signed --descriptor | jq .digest | xargs`
+	NOTATION_EXPERIMENTAL=1 .staging/notation/notation sign --timestamp-url ${TIMESTAMP_URL} --timestamp-root-cert ./test/bats/tests/certificates/tsarootca.cer --allow-referrers-api -u ${TEST_REGISTRY_USERNAME} -p ${TEST_REGISTRY_PASSWORD} ${TEST_REGISTRY}/notation@`${GITHUB_WORKSPACE}/bin/oras manifest fetch ${TEST_REGISTRY}/notation:tsa --descriptor | jq .digest | xargs`
 	NOTATION_EXPERIMENTAL=1 .staging/notation/notation sign --allow-referrers-api -u ${TEST_REGISTRY_USERNAME} -p ${TEST_REGISTRY_PASSWORD} ${TEST_REGISTRY}/all@`${GITHUB_WORKSPACE}/bin/oras manifest fetch ${TEST_REGISTRY}/all:v0 --descriptor | jq .digest | xargs`
 
 e2e-notation-leaf-cert-setup:
diff --git a/README.md b/README.md
index 3a5b438..93cce51 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,7 @@ Is a verification engine as a binary executable and on Kubernetes which enables
 [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/ratify-project/ratify/badge)](https://api.securityscorecards.dev/projects/github.com/ratify-project/ratify)
 [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9334/badge)](https://www.bestpractices.dev/projects/9334)
 [![Go Reference](https://pkg.go.dev/badge/github.com/deislabs/ratify.svg)](https://pkg.go.dev/github.com/deislabs/ratify)
+[![codecov](https://codecov.io/gh/ratify-project/ratify/graph/badge.svg?token=3X0BIPI4VD)](https://codecov.io/gh/ratify-project/ratify)
 
 ## Table of Contents
 
diff --git a/charts/ratify/README.md b/charts/ratify/README.md
index 84b52b2..10ec625 100644
--- a/charts/ratify/README.md
+++ b/charts/ratify/README.md
@@ -49,6 +49,7 @@ Values marked `# DEPRECATED` in the `values.yaml` as well as **DEPRECATED** in t
 | tolerations                                        | Pod tolerations for the Ratify deployment                                                                                                                                                                                                                                                                                                                              | `[]`                              |
 | notationCerts                                      | An array of public certificate/certificate chain used to create inline certstore used by Notation verifier                                                                                                                                                                                                                                                             | ``                                |
 | cosignKeys                                         | An array of public keys used to create inline key management providers used by Cosign verifier                                                                                                                                                                                                                                                                         | `[]`                              |
+| notation.enabled                                   | Enables/disables the built-in notation verifier. MUST be set to true for notation verification.                                                                                                                                                                                                                                                                        | `true`                            |
 | 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`.                                                                                                                                                                                                             | ``                                |
@@ -135,7 +136,8 @@ Values marked `# DEPRECATED` in the `values.yaml` as well as **DEPRECATED** in t
 | azurekeyvault.vaultURI                             | Vault URI for Azure Key Vault                                                                                                                                                                                                                                                                                                                                          | ``                                |
 | azurekeyvault.tenantId                             | Tenant ID of the configured Azure Key Vault resource                                                                                                                                                                                                                                                                                                                   | ``                                |
 | azurekeyvault.certificates                         | An array of certificate objects identified by `name` and `version` (optional) stored in Azure Key Vault                                                                                                                                                                                                                                                                | `[]`                              |
-| azurekeyvault.keys                                 | An array of key objects identified by `name` and `version` (optional) stored in Azure Key Vault                                                                                                                                                                                                                                                                        | `[]`                              |
+| azurekeyvault.keys                                 | An array of key objects identified by `name` and `version` (optional) stored in Azure Key Vault                                                                                                                                                                                                                  | `[]`                              |
+| azurekeyvault.refreshInterval                      | time duration to refresh the certificates/keys. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Example: 1h, 30m, 1h30m. If it's not set, the refresh functionality will be disabled.                                                                                                                                                                                                                      | ``                                |
 | notationCert                                       | **DEPRECATED** Please switch to `notationCerts` to specify an array of verification certificates. Public certificate/certificate chain used to create inline certstore used by Notation verifier.                                                                                                                                                                      | ``                                |
 | akvCertConfig.enabled                              | **DEPRECATED** Please use `azurekeyvault.enabled` instead. Enables/disables Azure Key Vault certificate store. If you are using a custom chart, certificate store should be referenced through a Verifier CR. References in ConfigMap will not be correctly resolved.                                                                                                  | `false`                           |
 | akvCertConfig.vaultURI                             | **DEPRECATED** Please use `azurekeyvault.vaultURI` instead. Vault URI for AKV configured                                                                                                                                                                                                                                                                               | ``                                |
diff --git a/charts/ratify/templates/akv-key-management-provider.yaml b/charts/ratify/templates/akv-key-management-provider.yaml
index 8314967..132c14f 100644
--- a/charts/ratify/templates/akv-key-management-provider.yaml
+++ b/charts/ratify/templates/akv-key-management-provider.yaml
@@ -8,6 +8,9 @@ metadata:
     helm.sh/hook-weight: "5"
 spec:
   type: azurekeyvault
+  {{- if .Values.azurekeyvault.refreshInterval }}
+  refreshInterval: {{ .Values.azurekeyvault.refreshInterval  }}
+  {{- end }}
   parameters:
     {{- if .Values.azurekeyvault.vaultURI }}
     vaultURI: {{ .Values.azurekeyvault.vaultURI  }}
diff --git a/charts/ratify/values.yaml b/charts/ratify/values.yaml
index f1206dc..2bc52a0 100644
--- a/charts/ratify/values.yaml
+++ b/charts/ratify/values.yaml
@@ -76,6 +76,7 @@ azurekeyvault:
   tenantId:
   certificates: []
   keys: []
+  refreshInterval:
 
 oras:
   useHttp: false
diff --git a/config/samples/clustered/verifier/config_v1beta1_verifier_notation.yaml b/config/samples/clustered/verifier/config_v1beta1_verifier_notation.yaml
index 8da1278..4da8453 100644
--- a/config/samples/clustered/verifier/config_v1beta1_verifier_notation.yaml
+++ b/config/samples/clustered/verifier/config_v1beta1_verifier_notation.yaml
@@ -6,10 +6,11 @@ spec:
   name: notation
   artifactTypes: application/vnd.cncf.notary.signature
   parameters:
-     verificationCertStores:
-       certs:
-         - ratify-notation-inline-cert-0
-     trustPolicyDoc:
+    verificationCertStores:
+      ca:
+        ca-certs:
+          - ratify-notation-inline-cert-0
+    trustPolicyDoc:
       version: "1.0"
       trustPolicies:
         - name: default
@@ -18,6 +19,6 @@ spec:
           signatureVerification:
             level: strict
           trustStores:
-            - ca:certs
+            - ca:ca-certs
           trustedIdentities:
             - "*"
diff --git a/config/samples/clustered/verifier/config_v1beta1_verifier_notation_kmprovider.yaml b/config/samples/clustered/verifier/config_v1beta1_verifier_notation_kmprovider.yaml
index 36caa15..ea2d24c 100644
--- a/config/samples/clustered/verifier/config_v1beta1_verifier_notation_kmprovider.yaml
+++ b/config/samples/clustered/verifier/config_v1beta1_verifier_notation_kmprovider.yaml
@@ -7,10 +7,9 @@ spec:
   artifactTypes: application/vnd.cncf.notary.signature
   parameters:
     verificationCertStores:
-      certs:
-        - kmprovider-akv
-      certs1:
-        - kmprovider-akv1
+      ca:
+        ca-certs:
+          - kmprovider-akv
     trustPolicyDoc:
       version: "1.0"
       trustPolicies:
@@ -20,6 +19,6 @@ spec:
           signatureVerification:
             level: strict
           trustStores:
-            - ca:certs
+            - ca:ca-certs
           trustedIdentities:
             - "*"
diff --git a/config/samples/clustered/verifier/config_v1beta1_verifier_notation_specificnskmprovider.yaml b/config/samples/clustered/verifier/config_v1beta1_verifier_notation_specificnskmprovider.yaml
index 1920a14..8584b99 100644
--- a/config/samples/clustered/verifier/config_v1beta1_verifier_notation_specificnskmprovider.yaml
+++ b/config/samples/clustered/verifier/config_v1beta1_verifier_notation_specificnskmprovider.yaml
@@ -6,10 +6,11 @@ spec:
   name: notation
   artifactTypes: application/vnd.cncf.notary.signature
   parameters:
-     verificationCertStores:
-       certs:
-         - default/ratify-notation-inline-cert-0
-     trustPolicyDoc:
+    verificationCertStores:
+      ca:
+        ca-certs:
+        - default/ratify-notation-inline-cert-0
+    trustPolicyDoc:
       version: "1.0"
       trustPolicies:
         - name: default
@@ -18,6 +19,6 @@ spec:
           signatureVerification:
             level: strict
           trustStores:
-            - ca:certs
+            - ca:ca-certs
           trustedIdentities:
             - "*"
diff --git a/config/samples/namespaced/verifier/config_v1beta1_verifier_notation.yaml b/config/samples/namespaced/verifier/config_v1beta1_verifier_notation.yaml
index b3c46c3..83f0d72 100644
--- a/config/samples/namespaced/verifier/config_v1beta1_verifier_notation.yaml
+++ b/config/samples/namespaced/verifier/config_v1beta1_verifier_notation.yaml
@@ -6,10 +6,11 @@ spec:
   name: notation
   artifactTypes: application/vnd.cncf.notary.signature
   parameters:
-     verificationCertStores:
-       certs:
-         - default/ratify-notation-inline-cert-0
-     trustPolicyDoc:
+    verificationCertStores:
+      ca:
+        ca-certs:
+          - default/ratify-notation-inline-cert-0
+    trustPolicyDoc:
       version: "1.0"
       trustPolicies:
         - name: default
@@ -18,6 +19,6 @@ spec:
           signatureVerification:
             level: strict
           trustStores:
-            - ca:certs
+            - ca:ca-certs
           trustedIdentities:
             - "*"
diff --git a/config/samples/namespaced/verifier/config_v1beta1_verifier_notation_kmprovider.yaml b/config/samples/namespaced/verifier/config_v1beta1_verifier_notation_kmprovider.yaml
index 447f959..e076c6c 100644
--- a/config/samples/namespaced/verifier/config_v1beta1_verifier_notation_kmprovider.yaml
+++ b/config/samples/namespaced/verifier/config_v1beta1_verifier_notation_kmprovider.yaml
@@ -7,10 +7,9 @@ spec:
   artifactTypes: application/vnd.cncf.notary.signature
   parameters:
     verificationCertStores:
-      certs:
-        - kmprovider-akv
-      certs1:
-        - kmprovider-akv1
+      ca:
+        ca-certs:
+          - kmprovider-akv
     trustPolicyDoc:
       version: "1.0"
       trustPolicies:
@@ -20,6 +19,6 @@ spec:
           signatureVerification:
             level: strict
           trustStores:
-            - ca:certs
+            - ca:ca-certs
           trustedIdentities:
             - "*"
diff --git a/config/samples/namespaced/verifier/config_v1beta1_verifier_notation_specificnskmprovider.yaml b/config/samples/namespaced/verifier/config_v1beta1_verifier_notation_specificnskmprovider.yaml
index b3c46c3..83f0d72 100644
--- a/config/samples/namespaced/verifier/config_v1beta1_verifier_notation_specificnskmprovider.yaml
+++ b/config/samples/namespaced/verifier/config_v1beta1_verifier_notation_specificnskmprovider.yaml
@@ -6,10 +6,11 @@ spec:
   name: notation
   artifactTypes: application/vnd.cncf.notary.signature
   parameters:
-     verificationCertStores:
-       certs:
-         - default/ratify-notation-inline-cert-0
-     trustPolicyDoc:
+    verificationCertStores:
+      ca:
+        ca-certs:
+          - default/ratify-notation-inline-cert-0
+    trustPolicyDoc:
       version: "1.0"
       trustPolicies:
         - name: default
@@ -18,6 +19,6 @@ spec:
           signatureVerification:
             level: strict
           trustStores:
-            - ca:certs
+            - ca:ca-certs
           trustedIdentities:
             - "*"
diff --git a/crd.Dockerfile b/crd.Dockerfile
index 92482cd..6606aa0 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:0a4eaa0eecf5f8c050e5bba433f58c052be7587ee8af3e8b3910ef9ab5fbe9f5 as builder
+FROM alpine@sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d as builder
 
 ARG TARGETOS
 ARG TARGETARCH
diff --git a/go.mod b/go.mod
index e9f40c2..5225b06 100644
--- a/go.mod
+++ b/go.mod
@@ -13,9 +13,9 @@ require (
 	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
 	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0
 	github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2
-	github.com/aws/aws-sdk-go-v2 v1.30.4
-	github.com/aws/aws-sdk-go-v2/config v1.27.31
-	github.com/aws/aws-sdk-go-v2/credentials v1.17.30
+	github.com/aws/aws-sdk-go-v2 v1.30.5
+	github.com/aws/aws-sdk-go-v2/config v1.27.33
+	github.com/aws/aws-sdk-go-v2/credentials v1.17.32
 	github.com/aws/aws-sdk-go-v2/service/ecr v1.28.6
 	github.com/cespare/xxhash/v2 v2.3.0
 	github.com/dapr/go-sdk v1.8.0
@@ -28,8 +28,9 @@ require (
 	github.com/golang/protobuf v1.5.4
 	github.com/google/go-containerregistry v0.20.2
 	github.com/gorilla/mux v1.8.1
-	github.com/notaryproject/notation-core-go v1.0.3
-	github.com/notaryproject/notation-go v1.0.1
+	github.com/notaryproject/notation-core-go v1.1.0
+	github.com/notaryproject/notation-go v1.2.1
+	github.com/notaryproject/notation-plugin-framework-go v1.0.0
 	github.com/open-policy-agent/cert-controller v0.8.0
 	github.com/open-policy-agent/frameworks/constraint v0.0.0-20230411224310-3f237e2710fa
 	github.com/open-policy-agent/opa v0.63.0
@@ -38,7 +39,7 @@ require (
 	github.com/owenrumney/go-sarif/v2 v2.3.3
 	github.com/pkg/errors v0.9.1
 	github.com/sigstore/cosign/v2 v2.2.4
-	github.com/sigstore/sigstore v1.8.8
+	github.com/sigstore/sigstore v1.8.9
 	github.com/sirupsen/logrus v1.9.3
 	github.com/spdx/tools-golang v0.5.5
 	github.com/spf13/cobra v1.8.1
@@ -46,7 +47,7 @@ require (
 	go.opentelemetry.io/otel/exporters/prometheus v0.49.0
 	go.opentelemetry.io/otel/metric v1.27.0
 	go.opentelemetry.io/otel/sdk/metric v1.27.0
-	golang.org/x/sync v0.7.0
+	golang.org/x/sync v0.8.0
 	google.golang.org/grpc v1.64.1
 	google.golang.org/protobuf v1.34.2
 	k8s.io/api v0.28.13
@@ -97,7 +98,7 @@ require (
 	github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
 	github.com/go-ini/ini v1.67.0 // indirect
 	github.com/go-jose/go-jose/v4 v4.0.2 // indirect
-	github.com/go-ldap/ldap/v3 v3.4.6 // indirect
+	github.com/go-ldap/ldap/v3 v3.4.8 // indirect
 	github.com/gobwas/glob v0.2.3 // indirect
 	github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
 	github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
@@ -107,6 +108,7 @@ require (
 	github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
 	github.com/miekg/pkcs11 v1.1.1 // indirect
 	github.com/mozillazg/docker-credential-acr-helper v0.3.0 // indirect
+	github.com/notaryproject/tspclient-go v0.2.0 // indirect
 	github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect
 	github.com/sagikazarmark/locafero v0.4.0 // indirect
 	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
@@ -136,14 +138,14 @@ require (
 	github.com/Azure/go-autorest/tracing v0.6.0 // indirect
 	github.com/OneOfOne/xxhash v1.2.8 // indirect
 	github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
-	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect
-	github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect
-	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect
+	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 // indirect
 	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
-	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect
-	github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect
-	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect
-	github.com/aws/aws-sdk-go-v2/service/sts v1.30.5 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sso v1.22.7 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sts v1.30.7 // indirect
 	github.com/aws/smithy-go v1.20.4 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/blang/semver v3.5.1+incompatible // indirect
@@ -153,7 +155,7 @@ require (
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // 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.6.0 // indirect
+	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
 	github.com/go-chi/chi v4.1.2+incompatible // indirect
 	github.com/go-logr/logr v1.4.2
 	github.com/go-logr/stdr v1.2.2 // indirect
@@ -231,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.25.0
+	golang.org/x/crypto v0.26.0
 	golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
-	golang.org/x/mod v0.17.0 // indirect
+	golang.org/x/mod v0.20.0 // indirect
 	golang.org/x/net v0.27.0 // indirect
 	golang.org/x/oauth2 v0.22.0 // indirect
-	golang.org/x/sys v0.22.0 // indirect
-	golang.org/x/term v0.22.0 // indirect
-	golang.org/x/text v0.16.0 // indirect
+	golang.org/x/sys v0.23.0 // indirect
+	golang.org/x/term v0.23.0 // indirect
+	golang.org/x/text v0.17.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 3592787..8577130 100644
--- a/go.sum
+++ b/go.sum
@@ -72,8 +72,8 @@ github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRB
 github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
 github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
 github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
-github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA=
-github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
+github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI=
+github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
 github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.2/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
 github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo=
 github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
@@ -125,18 +125,18 @@ 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.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8=
-github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0=
-github.com/aws/aws-sdk-go-v2/config v1.27.31 h1:kxBoRsjhT3pq0cKthgj6RU6bXTm/2SgdoUMyrVw0rAI=
-github.com/aws/aws-sdk-go-v2/config v1.27.31/go.mod h1:z04nZdSWFPaDwK3DdJOG2r+scLQzMYuJeW0CujEm9FM=
-github.com/aws/aws-sdk-go-v2/credentials v1.17.30 h1:aau/oYFtibVovr2rDt8FHlU17BTicFEMAi29V1U+L5Q=
-github.com/aws/aws-sdk-go-v2/credentials v1.17.30/go.mod h1:BPJ/yXV92ZVq6G8uYvbU0gSl8q94UB63nMT5ctNO38g=
-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE=
-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs=
+github.com/aws/aws-sdk-go-v2 v1.30.5 h1:mWSRTwQAb0aLE17dSzztCVJWI9+cRMgqebndjwDyK0g=
+github.com/aws/aws-sdk-go-v2 v1.30.5/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0=
+github.com/aws/aws-sdk-go-v2/config v1.27.33 h1:Nof9o/MsmH4oa0s2q9a0k7tMz5x/Yj5k06lDODWz3BU=
+github.com/aws/aws-sdk-go-v2/config v1.27.33/go.mod h1:kEqdYzRb8dd8Sy2pOdEbExTTF5v7ozEXX0McgPE7xks=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.32 h1:7Cxhp/BnT2RcGy4VisJ9miUPecY+lyE9I8JvcZofn9I=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.32/go.mod h1:P5/QMF3/DCHbXGEGkdbilXHsyTBX5D3HSwcrSc9p20I=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 h1:pfQ2sqNpMVK6xz2RbqLEL0GH87JOwSxPV2rzm8Zsb74=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13/go.mod h1:NG7RXPUlqfsCLLFfi0+IpKN4sCB9D9fw/qTaSB+xRoU=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 h1:pI7Bzt0BJtYA0N/JEC6B8fJ4RBrEMi1LBrkMdFYNSnQ=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17/go.mod h1:Dh5zzJYMtxfIjYW+/evjQ8uj2OyR/ve2KROHGHlSFqE=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 h1:Mqr/V5gvrhA2gvgnF42Zh5iMiQNcOYthFYwCyrnuWlc=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17/go.mod h1:aLJpZlCmjE+V+KtN1q1uyZkfnUWpQGpbsn89XPKyzfU=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
 github.com/aws/aws-sdk-go-v2/service/ecr v1.28.6 h1:CnQNpQv+WGl5aECyAXrJ4w+Qccz2aC/uXg2OjxiPl30=
@@ -145,16 +145,16 @@ github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.7 h1:dsmihXaPkhFuUTiL+ygm9R
 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.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 h1:rfprUlsdzgl7ZL2KlXiUAoJnI/VxfHCvDFr2QDFj6u4=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19/go.mod h1:SCWkEdRq8/7EK60NcvvQ6NXKuTcchAD4ROAsC37VEZE=
 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.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c=
-github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac=
-github.com/aws/aws-sdk-go-v2/service/sts v1.30.5 h1:OMsEmCyz2i89XwRwPouAJvhj81wINh+4UK+k/0Yo/q8=
-github.com/aws/aws-sdk-go-v2/service/sts v1.30.5/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0=
+github.com/aws/aws-sdk-go-v2/service/sso v1.22.7 h1:pIaGg+08llrP7Q5aiz9ICWbY8cqhTkyy+0SHvfzQpTc=
+github.com/aws/aws-sdk-go-v2/service/sso v1.22.7/go.mod h1:eEygMHnTKH/3kNp9Jr1n3PdejuSNcgwLe1dWgQtO0VQ=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7 h1:/Cfdu0XV3mONYKaOt1Gr0k1KvQzkzPyiKUdlWJqy+J4=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.7/go.mod h1:bCbAxKDqNvkHxRaIMnyVPXPo+OaPRwvmgzMxbz1VKSA=
+github.com/aws/aws-sdk-go-v2/service/sts v1.30.7 h1:NKTa1eqZYw8tiHSRGpP0VtTdub/8KNk8sDkNPFaOKDE=
+github.com/aws/aws-sdk-go-v2/service/sts v1.30.7/go.mod h1:NXi1dIAGteSaRLqYgarlhP/Ij0cFT+qmCwiJqWh/U5o=
 github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4=
 github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
 github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 h1:SoFYaT9UyGkR0+nogNyD/Lj+bsixB+SNuAS4ABlEs6M=
@@ -273,8 +273,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.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA=
-github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
+github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
+github.com/fxamacker/cbor/v2 v2.7.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=
@@ -285,8 +285,8 @@ github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7
 github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
 github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
 github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
-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-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ=
+github.com/go-ldap/ldap/v3 v3.4.8/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
 github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@@ -391,7 +391,6 @@ github.com/google/tink/go v1.7.0 h1:6Eox8zONGebBFcCBqkVmt60LaWZa6xg1cl/DwAh/J1w=
 github.com/google/tink/go v1.7.0/go.mod h1:GAUOd+QE3pgj9q8VKIGTCP33c/B7eb4NhxLcgTJZStM=
 github.com/google/trillian v1.6.0 h1:jMBeDBIkINFvS2n6oV5maDqfRlxREAc6CW9QYWQ0qT4=
 github.com/google/trillian v1.6.0/go.mod h1:Yu3nIMITzNhhMJEHjAtp6xKiu+H/iHu2Oq5FjV2mCWI=
-github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
@@ -402,6 +401,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
 github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
 github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
+github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
+github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
 github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
 github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
@@ -423,6 +424,9 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9
 github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
 github.com/hashicorp/go-sockaddr v1.0.5 h1:dvk7TIXCZpmfOlM+9mlcrWmWjw/wlKT+VDq2wMvfPJU=
 github.com/hashicorp/go-sockaddr v1.0.5/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI=
+github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
+github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM=
 github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
 github.com/hashicorp/vault/api v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE=
@@ -437,6 +441,18 @@ github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ
 github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3lUTQd+eF9HdeMo=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
+github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
+github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
+github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
+github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=
+github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
+github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
+github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
+github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=
+github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
+github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
+github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
 github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY=
 github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E=
 github.com/jellydator/ttlcache/v3 v3.2.0 h1:6lqVJ8X3ZaUwvzENqPAobDsXNExfUJd61u++uW8a3LE=
@@ -500,10 +516,14 @@ github.com/mozillazg/docker-credential-acr-helper v0.3.0/go.mod h1:cZlu3tof523uj
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-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/notaryproject/notation-core-go v1.1.0 h1:xCybcONOKcCyPNihJUSa+jRNsyQFNkrk0eJVVs1kWeg=
+github.com/notaryproject/notation-core-go v1.1.0/go.mod h1:+6AOh41JPrnVLbW/19SJqdhVHwKgIINBO/np0e7nXJA=
+github.com/notaryproject/notation-go v1.2.1 h1:fbCMBcvg1xttrisd5CyM60QDectGYYF701Us0M3cKN8=
+github.com/notaryproject/notation-go v1.2.1/go.mod h1:re9V+TfuNRaUq5e3NuNcCJN53++sL2KbnJrjGyOUpgE=
+github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4=
+github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics=
+github.com/notaryproject/tspclient-go v0.2.0 h1:g/KpQGmyk/h7j60irIRG1mfWnibNOzJ8WhLqAzuiQAQ=
+github.com/notaryproject/tspclient-go v0.2.0/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs=
 github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 h1:Up6+btDp321ZG5/zdSLo48H9Iaq0UQGthrhWC6pCxzE=
 github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481/go.mod h1:yKZQO8QE2bHlgozqWDiRVqTFlLQSj30K/6SAK8EeYFw=
 github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
@@ -593,8 +613,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.8 h1:B6ZQPBKK7Z7tO3bjLNnlCMG+H66tO4E/+qAphX8T/hg=
-github.com/sigstore/sigstore v1.8.8/go.mod h1:GW0GgJSCTBJY3fUOuGDHeFWcD++c4G8Y9K015pwcpDI=
+github.com/sigstore/sigstore v1.8.9 h1:NiUZIVWywgYuVTxXmRoTT4O4QAGiTEKup4N1wdxFadk=
+github.com/sigstore/sigstore v1.8.9/go.mod h1:d9ZAbNDs8JJfxJrYmulaTazU3Pwr8uLL9+mii4BNR3w=
 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=
@@ -646,6 +666,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
@@ -756,11 +777,11 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
 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.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
-golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
+golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
+golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
+golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
 golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
@@ -771,8 +792,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
-golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
+golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -781,6 +802,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
@@ -799,6 +821,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
 golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
 golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -812,8 +836,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -844,11 +868,11 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 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.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
-golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
+golang.org/x/sys v0.23.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=
@@ -856,11 +880,11 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 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.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
-golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
+golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
+golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
+golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -872,10 +896,9 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 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/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
 golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/httpserver/Dockerfile b/httpserver/Dockerfile
index 85b6256..6483cb6 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.22@sha256:367bb5295d3103981a86a572651d8297d6973f2ec8b62f716b007860e22cbc25 as builder
+FROM --platform=$BUILDPLATFORM golang:1.22@sha256:192683db8982323952988c7b86c098ee7ecc6cbeb202bf7c113ff9be5358367c as builder
 
 ARG TARGETPLATFORM
 ARG TARGETOS
@@ -41,7 +41,7 @@ RUN if [ "$build_licensechecker" = "true" ]; then go build -o /app/out/plugins/
 RUN if [ "$build_schemavalidator" = "true" ]; then go build -o /app/out/plugins/ /app/plugins/verifier/schemavalidator; fi
 RUN if [ "$build_vulnerabilityreport" = "true" ]; then go build -o /app/out/plugins/ /app/plugins/verifier/vulnerabilityreport; fi
 
-FROM gcr.io/distroless/static:nonroot@sha256:8dd8d3ca2cf283383304fd45a5c9c74d5f2cd9da8d3b077d720e264880077c65
+FROM gcr.io/distroless/static:nonroot@sha256:42d15c647a762d3ce3a67eab394220f5268915d6ddba9006871e16e4698c3a24
 LABEL org.opencontainers.image.source https://github.com/ratify-project/ratify
 
 ARG RATIFY_FOLDER=$HOME/.ratify/
diff --git a/pkg/controllers/clusterresource/verifier_controller.go b/pkg/controllers/clusterresource/verifier_controller.go
index 2b72459..c8c8cd8 100644
--- a/pkg/controllers/clusterresource/verifier_controller.go
+++ b/pkg/controllers/clusterresource/verifier_controller.go
@@ -17,6 +17,7 @@ package clusterresource
 
 import (
 	"context"
+	"fmt"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
 	re "github.com/ratify-project/ratify/errors"
@@ -82,12 +83,13 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 	return ctrl.Result{}, nil
 }
 
-// creates a verifier reference from CRD spec and add store to map
+// creates a verifier reference from CR spec and add verifier to map
 func verifierAddOrReplace(spec configv1beta1.VerifierSpec, objectName string) error {
 	verifierConfig, err := cutils.SpecToVerifierConfig(spec.Parameters.Raw, objectName, spec.Name, spec.ArtifactTypes, spec.Source)
 	if err != nil {
-		logrus.Error(err)
-		return err
+		errMsg := fmt.Sprintf("Unable to apply cluster-wide resource %s of Verifier kind", objectName)
+		logrus.Error(err, errMsg)
+		return re.ErrorCodeConfigInvalid.WithDetail(errMsg).WithError(err)
 	}
 
 	return cutils.UpsertVerifier(spec.Version, spec.Address, constants.EmptyNamespace, objectName, verifierConfig)
diff --git a/pkg/controllers/namespaceresource/verifier_controller.go b/pkg/controllers/namespaceresource/verifier_controller.go
index e78bd8d..4b19b61 100644
--- a/pkg/controllers/namespaceresource/verifier_controller.go
+++ b/pkg/controllers/namespaceresource/verifier_controller.go
@@ -17,6 +17,7 @@ package namespaceresource
 
 import (
 	"context"
+	"fmt"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
 	"github.com/ratify-project/ratify/internal/constants"
@@ -85,8 +86,9 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 func verifierAddOrReplace(spec configv1beta1.NamespacedVerifierSpec, objectName string, namespace string) error {
 	verifierConfig, err := cutils.SpecToVerifierConfig(spec.Parameters.Raw, objectName, spec.Name, spec.ArtifactTypes, spec.Source)
 	if err != nil {
-		logrus.Error(err)
-		return err
+		errMsg := fmt.Sprintf("Unable to apply the resource %s of NamespacedVerifier kind in the namespace %s", objectName, namespace)
+		logrus.Error(err, errMsg)
+		return re.ErrorCodeConfigInvalid.WithDetail(errMsg).WithError(err)
 	}
 
 	return cutils.UpsertVerifier(spec.Version, spec.Address, namespace, objectName, verifierConfig)
diff --git a/pkg/controllers/utils/verifier.go b/pkg/controllers/utils/verifier.go
index 0b25579..e65a059 100644
--- a/pkg/controllers/utils/verifier.go
+++ b/pkg/controllers/utils/verifier.go
@@ -15,8 +15,10 @@ package utils
 
 import (
 	"encoding/json"
+	"fmt"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	vc "github.com/ratify-project/ratify/pkg/verifier/config"
 	vf "github.com/ratify-project/ratify/pkg/verifier/factory"
 	"github.com/ratify-project/ratify/pkg/verifier/types"
@@ -56,8 +58,9 @@ func SpecToVerifierConfig(raw []byte, verifierName, verifierType, artifactTypes
 
 	if string(raw) != "" {
 		if err := json.Unmarshal(raw, &verifierConfig); err != nil {
-			logrus.Error(err, "unable to decode verifier parameters", "Parameters.Raw", raw)
-			return vc.VerifierConfig{}, err
+			errMsg := fmt.Sprintf("Unable to recognize the parameters of the Verifier resource %s", string(raw))
+			logrus.Error(err, errMsg)
+			return vc.VerifierConfig{}, re.ErrorCodeConfigInvalid.WithError(err).WithDetail(errMsg).WithRemediation("Please update the Verifier parameters and try again. Refer to the Verifier configuration guide: https://ratify.dev/docs/reference/custom%20resources/verifiers")
 		}
 	}
 	verifierConfig[types.Name] = verifierName
diff --git a/pkg/executor/core/executor.go b/pkg/executor/core/executor.go
index e5d8ec2..b364bee 100644
--- a/pkg/executor/core/executor.go
+++ b/pkg/executor/core/executor.go
@@ -61,7 +61,7 @@ type Executor struct {
 // VerifySubject verifies the subject and returns results.
 func (executor Executor) VerifySubject(ctx context.Context, verifyParameters e.VerifyParameters) (types.VerifyResult, error) {
 	if executor.PolicyEnforcer == nil {
-		return types.VerifyResult{}, errors.ErrorCodePolicyProviderNotFound.WithComponentType(errors.Executor)
+		return types.VerifyResult{}, errors.ErrorCodePolicyProviderNotFound.WithDetail("Policy configuration not found")
 	}
 	result, err := executor.verifySubjectInternal(ctx, verifyParameters)
 	if err != nil {
@@ -83,7 +83,7 @@ func (executor Executor) verifySubjectInternal(ctx context.Context, verifyParame
 	}
 	if executor.PolicyEnforcer.GetPolicyType(ctx) == pt.ConfigPolicy {
 		if len(verifierReports) == 0 {
-			return types.VerifyResult{}, errors.ErrorCodeNoVerifierReport.WithComponentType(errors.Executor).WithDescription()
+			return types.VerifyResult{}, errors.ErrorCodeNoVerifierReport.WithDetail(fmt.Sprintf("No verification results for the artifact %s. Ensure verifiers are properly configured and that artifact metadata is attached", verifyParameters.Subject))
 		}
 	}
 	// If it requires embedded Rego Policy Engine make the decision, execute
@@ -176,7 +176,7 @@ func (executor Executor) verifyReferenceForJSONPolicy(ctx context.Context, subje
 			verifierStartTime := time.Now()
 			verifyResult, err := verifier.Verify(ctx, subjectRef, referenceDesc, referrerStore)
 			if err != nil {
-				verifierErr := errors.ErrorCodeVerifyReferenceFailure.NewError(errors.Verifier, verifier.Name(), errors.EmptyLink, err, nil, errors.HideStackTrace)
+				verifierErr := errors.ErrorCodeVerifyReferenceFailure.WithError(err)
 				verifyResult = vr.NewVerifierResult("", verifier.Name(), verifier.Type(), "", false, &verifierErr, nil)
 			}
 
@@ -224,7 +224,7 @@ func (executor Executor) verifyReferenceForRegoPolicy(ctx context.Context, subje
 			verifierStartTime := time.Now()
 			verifierResult, err := verifier.Verify(errCtx, subjectRef, referenceDesc, referrerStore)
 			if err != nil {
-				verifierErr := errors.ErrorCodeVerifyReferenceFailure.NewError(errors.Verifier, verifier.Name(), errors.EmptyLink, err, nil, errors.HideStackTrace)
+				verifierErr := errors.ErrorCodeVerifyReferenceFailure.WithError(err)
 				verifierReport = vt.CreateVerifierResult(verifier.Name(), verifier.Type(), "", false, &verifierErr)
 			} else {
 				verifierReport = vt.NewVerifierResult(verifierResult)
@@ -288,7 +288,7 @@ func (executor Executor) addNestedReports(ctx context.Context, referenceDes ocis
 	for _, report := range reports.VerifierReports {
 		nestedReport, err := types.NewNestedVerifierReport(report)
 		if err != nil {
-			return errors.ErrorCodeExecutorFailure.WithError(err).WithComponentType(errors.Executor)
+			return errors.ErrorCodeExecutorFailure.WithError(err)
 		}
 		nestedReports = append(nestedReports, nestedReport)
 	}
diff --git a/pkg/keymanagementprovider/keymanagementprovider.go b/pkg/keymanagementprovider/keymanagementprovider.go
index bf77c2c..584f508 100644
--- a/pkg/keymanagementprovider/keymanagementprovider.go
+++ b/pkg/keymanagementprovider/keymanagementprovider.go
@@ -136,7 +136,7 @@ func setCertificatesInMap(resource string, certs map[KMPMapKey][]*x509.Certifica
 // GetCertificatesFromMap gets the certificates from the map and returns an empty map of certificate arrays if not found or an error happened.
 func GetCertificatesFromMap(ctx context.Context, resource string) (map[KMPMapKey][]*x509.Certificate, error) {
 	if !hasAccessToProvider(ctx, resource) {
-		return map[KMPMapKey][]*x509.Certificate{}, errors.ErrorCodeForbidden.WithDetail(fmt.Sprintf("namespace: [%s] does not have access to key management provider: %s", ctxUtils.GetNamespace(ctx), resource)).WithRemediation(fmt.Sprintf("Ensure the key management provider: %s is created under namespace: [%s] or as a cluster-wide resource.", resource, ctxUtils.GetNamespace(ctx)))
+		return map[KMPMapKey][]*x509.Certificate{}, errors.ErrorCodeForbidden.WithDetail(fmt.Sprintf("Resources in namespace [%s] do not have access to key management provider [%s]", ctxUtils.GetNamespace(ctx), resource)).WithRemediation(fmt.Sprintf("Make sure the key management provider: %s is created in the namespace: [%s] or as a cluster-wide resource.", resource, ctxUtils.GetNamespace(ctx)))
 	}
 	if err, ok := certificateErrMap.Load(resource); ok && err != nil {
 		return map[KMPMapKey][]*x509.Certificate{}, err.(error)
@@ -144,7 +144,7 @@ func GetCertificatesFromMap(ctx context.Context, resource string) (map[KMPMapKey
 	if certs, ok := certificatesMap.Load(resource); ok {
 		return certs.(map[KMPMapKey][]*x509.Certificate), nil
 	}
-	return map[KMPMapKey][]*x509.Certificate{}, errors.ErrorCodeNotFound.WithDetail(fmt.Sprintf("failed to access non-existent key management provider: %s", resource))
+	return map[KMPMapKey][]*x509.Certificate{}, errors.ErrorCodeNotFound.WithDetail(fmt.Sprintf("The key management provider [%s] does not exist", resource)).WithRemediation(fmt.Sprintf("Make sure the key management provider: %s is created in the namespace: [%s] or as a cluster-wide resource.", resource, ctxUtils.GetNamespace(ctx)))
 }
 
 // DeleteResourceFromMap deletes the certificates, keys and errors from the map
@@ -186,7 +186,7 @@ func GetKeysFromMap(ctx context.Context, resource string) (map[KMPMapKey]PublicK
 	// A cluster-wide operation can access cluster-wide provider
 	// A namespaced operation can only fetch the provider in the same namespace or cluster-wide provider.
 	if !hasAccessToProvider(ctx, resource) {
-		return map[KMPMapKey]PublicKey{}, fmt.Errorf("namespace: [%s] does not have access to key management provider: %s", ctxUtils.GetNamespace(ctx), resource)
+		return map[KMPMapKey]PublicKey{}, errors.ErrorCodeForbidden.WithDetail(fmt.Sprintf("The resources in namespace [%s] do not have access to key management provider [%s]", ctxUtils.GetNamespace(ctx), resource)).WithRemediation(fmt.Sprintf("Make sure the key management provider [%s] is created in the namespace [%s] or as a cluster-wide resource.", resource, ctxUtils.GetNamespace(ctx)))
 	}
 	if err, ok := keyErrMap.Load(resource); ok && err != nil {
 		return map[KMPMapKey]PublicKey{}, err.(error)
@@ -194,7 +194,7 @@ func GetKeysFromMap(ctx context.Context, resource string) (map[KMPMapKey]PublicK
 	if keys, ok := keyMap.Load(resource); ok {
 		return keys.(map[KMPMapKey]PublicKey), nil
 	}
-	return map[KMPMapKey]PublicKey{}, fmt.Errorf("failed to access non-existent key management provider: %s", resource)
+	return map[KMPMapKey]PublicKey{}, errors.ErrorCodeNotFound.WithDetail(fmt.Sprintf("The key management provider [%s] does not exist", resource)).WithRemediation(fmt.Sprintf("Make sure the key management provider: %s is created in the namespace: [%s] or as a cluster-wide resource.", resource, ctxUtils.GetNamespace(ctx)))
 }
 
 // SetCertificateError sets the error while fetching certificates from key management provider.
diff --git a/pkg/referrerstore/oras/oras.go b/pkg/referrerstore/oras/oras.go
index 0a8f146..a8462d2 100644
--- a/pkg/referrerstore/oras/oras.go
+++ b/pkg/referrerstore/oras/oras.go
@@ -313,7 +313,7 @@ func (store *orasStore) GetBlobContent(ctx context.Context, subjectReference com
 func (store *orasStore) GetReferenceManifest(ctx context.Context, subjectReference common.Reference, referenceDesc ocispecs.ReferenceDescriptor) (ocispecs.ReferenceManifest, error) {
 	repository, err := store.createRepository(ctx, store, subjectReference)
 	if err != nil {
-		return ocispecs.ReferenceManifest{}, re.ErrorCodeCreateRepositoryFailure.NewError(re.ReferrerStore, storeName, re.EmptyLink, err, nil, re.HideStackTrace)
+		return ocispecs.ReferenceManifest{}, re.ErrorCodeRepositoryOperationFailure.WithDetail("Failed to connect to the remote registry").WithError(err)
 	}
 	var manifestBytes []byte
 	// check if manifest exists in local ORAS cache
@@ -336,12 +336,12 @@ func (store *orasStore) GetReferenceManifest(ctx context.Context, subjectReferen
 		manifestReader, err := repository.Fetch(ctx, referenceDesc.Descriptor)
 		if err != nil {
 			evictOnError(ctx, err, subjectReference.Original)
-			return ocispecs.ReferenceManifest{}, re.ErrorCodeRepositoryOperationFailure.NewError(re.ReferrerStore, storeName, re.EmptyLink, err, nil, re.HideStackTrace)
+			return ocispecs.ReferenceManifest{}, re.ErrorCodeRepositoryOperationFailure.WithDetail("Failed to fetch the artifact metadata from the registry").WithError(err)
 		}
 
 		manifestBytes, err = io.ReadAll(manifestReader)
 		if err != nil {
-			return ocispecs.ReferenceManifest{}, re.ErrorCodeManifestInvalid.WithError(err).WithPluginName(storeName).WithComponentType(re.ReferrerStore)
+			return ocispecs.ReferenceManifest{}, re.ErrorCodeManifestInvalid.WithDetail("Failed to parse the artifact metadata").WithError(err)
 		}
 
 		// push fetched manifest to local ORAS cache
@@ -360,15 +360,15 @@ func (store *orasStore) GetReferenceManifest(ctx context.Context, subjectReferen
 	if referenceDesc.Descriptor.MediaType == oci.MediaTypeImageManifest {
 		var imageManifest oci.Manifest
 		if err := json.Unmarshal(manifestBytes, &imageManifest); err != nil {
-			return ocispecs.ReferenceManifest{}, re.ErrorCodeDataDecodingFailure.WithError(err).WithComponentType(re.ReferrerStore)
+			return ocispecs.ReferenceManifest{}, re.ErrorCodeDataDecodingFailure.WithDetail("Failed to parse artifact metadata of mediatype `application/vnd.oci.image.manifest.v1+json`").WithError(err).WithRemediation("Please check if the artifact metadata was created correctly.")
 		}
 		referenceManifest = commonutils.OciManifestToReferenceManifest(imageManifest)
 	} else if referenceDesc.Descriptor.MediaType == ocispecs.MediaTypeArtifactManifest {
 		if err := json.Unmarshal(manifestBytes, &referenceManifest); err != nil {
-			return ocispecs.ReferenceManifest{}, re.ErrorCodeDataDecodingFailure.WithError(err).WithComponentType(re.ReferrerStore)
+			return ocispecs.ReferenceManifest{}, re.ErrorCodeDataDecodingFailure.WithDetail("Failed to parse artifact metadata of mediatype `application/vnd.oci.artifact.manifest.v1+json`").WithError(err).WithRemediation("Please check if the artifact metadata was created correctly.")
 		}
 	} else {
-		return ocispecs.ReferenceManifest{}, fmt.Errorf("unsupported manifest media type: %s", referenceDesc.Descriptor.MediaType)
+		return ocispecs.ReferenceManifest{}, re.ErrorCodeGetReferenceManifestFailure.WithDetail(fmt.Sprintf("Unsupported artifact metadata of media type %s", referenceDesc.Descriptor.MediaType)).WithRemediation("Please check if the artifact metadata was created correctly.")
 	}
 
 	return referenceManifest, nil
@@ -377,13 +377,13 @@ func (store *orasStore) GetReferenceManifest(ctx context.Context, subjectReferen
 func (store *orasStore) GetSubjectDescriptor(ctx context.Context, subjectReference common.Reference) (*ocispecs.SubjectDescriptor, error) {
 	repository, err := store.createRepository(ctx, store, subjectReference)
 	if err != nil {
-		return nil, re.ErrorCodeCreateRepositoryFailure.WithError(err).WithComponentType(re.ReferrerStore).WithPluginName(storeName)
+		return nil, re.ErrorCodeRepositoryOperationFailure.WithDetail("Failed to connect to remote registry").WithError(err)
 	}
 
 	desc, err := repository.Resolve(ctx, subjectReference.Original)
 	if err != nil {
 		evictOnError(ctx, err, subjectReference.Original)
-		return nil, re.ErrorCodeRepositoryOperationFailure.WithError(err).WithPluginName(storeName)
+		return nil, re.ErrorCodeRepositoryOperationFailure.WithDetail(fmt.Sprintf("Unable to resolve the reference: %s", subjectReference.Original)).WithError(err)
 	}
 
 	return &ocispecs.SubjectDescriptor{Descriptor: desc}, nil
diff --git a/pkg/verifier/factory/factory.go b/pkg/verifier/factory/factory.go
index a23bdcf..fdc6e57 100644
--- a/pkg/verifier/factory/factory.go
+++ b/pkg/verifier/factory/factory.go
@@ -53,12 +53,12 @@ func Register(name string, factory VerifierFactory) {
 // namespace is only applicable in K8s environment, namespace is appended to the certstore of the truststore so it is uniquely identifiable in a cluster env
 // the first element of pluginBinDir will be used as the plugin directory
 func CreateVerifierFromConfig(verifierConfig config.VerifierConfig, configVersion string, pluginBinDir []string, namespace string) (verifier.ReferenceVerifier, error) {
-	// in cli mode both `type` and `name`` are read from config, if `type` is not specified, `name` is used as `type`
+	// in cli mode both `type` and `name` are read from config, if `type` is not specified, `name` is used as `type`
 	var verifierTypeStr string
 	if value, ok := verifierConfig[types.Name]; ok {
 		verifierTypeStr = value.(string)
 	} else {
-		return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithDetail(fmt.Sprintf("failed to find verifier name in the verifier config with key %s", "name"))
+		return nil, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("The name field is required in the Verifier configuration: %+v", verifierConfig))
 	}
 
 	if value, ok := verifierConfig[types.Type]; ok {
@@ -66,7 +66,7 @@ func CreateVerifierFromConfig(verifierConfig config.VerifierConfig, configVersio
 	}
 
 	if strings.ContainsRune(verifierTypeStr, os.PathSeparator) {
-		return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithDetail(fmt.Sprintf("invalid plugin name for a verifier: %s", verifierTypeStr))
+		return nil, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("Invalid name [%s] in the Verifier configuration, [%v] is disallowed", verifierTypeStr, os.PathSeparator))
 	}
 
 	// if source is specified, download the plugin
@@ -74,13 +74,13 @@ func CreateVerifierFromConfig(verifierConfig config.VerifierConfig, configVersio
 		if featureflag.DynamicPlugins.Enabled {
 			source, err := pluginCommon.ParsePluginSource(source)
 			if err != nil {
-				return nil, re.ErrorCodeConfigInvalid.NewError(re.Verifier, "", re.EmptyLink, err, "failed to parse plugin source", re.HideStackTrace)
+				return nil, re.ErrorCodeConfigInvalid.WithDetail("Failed to parse the plugin source").WithError(err)
 			}
 
 			targetPath := path.Join(pluginBinDir[0], verifierTypeStr)
 			err = pluginCommon.DownloadPlugin(source, targetPath)
 			if err != nil {
-				return nil, re.ErrorCodeDownloadPluginFailure.NewError(re.Verifier, "", re.EmptyLink, err, "failed to download plugin", re.HideStackTrace)
+				return nil, re.ErrorCodeDownloadPluginFailure.WithDetail("Failed to download the plugin from the source").WithError(err)
 			}
 			logrus.Infof("downloaded verifier plugin %s from %s to %s", verifierTypeStr, source.Artifact, targetPath)
 		} else {
@@ -94,7 +94,7 @@ func CreateVerifierFromConfig(verifierConfig config.VerifierConfig, configVersio
 	}
 
 	if _, err := pluginCommon.FindInPaths(verifierTypeStr, pluginBinDir); err != nil {
-		return nil, re.ErrorCodePluginNotFound.NewError(re.Verifier, "", re.EmptyLink, err, "plugin not found", re.HideStackTrace)
+		return nil, re.ErrorCodePluginNotFound.WithDetail(fmt.Sprintf("Verifier plugin %s not found", verifierTypeStr)).WithError(err).WithRemediation("Please ensure that the correct type is specified for the built-in Verifier configuration or the custom Verifier plugin is configured.")
 	}
 
 	pluginVersion := configVersion
@@ -113,11 +113,11 @@ func CreateVerifiersFromConfig(verifiersConfig config.VerifiersConfig, defaultPl
 
 	err := validateVerifiersConfig(&verifiersConfig)
 	if err != nil {
-		return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithError(err)
+		return nil, re.ErrorCodeConfigInvalid.WithError(err)
 	}
 
 	if len(verifiersConfig.Verifiers) == 0 {
-		return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithDetail("verifiers config should have at least one verifier")
+		return nil, re.ErrorCodeConfigInvalid.WithDetail("The configuration for verifier.plugins must include at least one plugin")
 	}
 
 	verifiers := make([]verifier.ReferenceVerifier, 0)
@@ -131,7 +131,7 @@ func CreateVerifiersFromConfig(verifiersConfig config.VerifiersConfig, defaultPl
 	for _, verifierConfig := range verifiersConfig.Verifiers {
 		verifier, err := CreateVerifierFromConfig(verifierConfig, verifiersConfig.Version, verifiersConfig.PluginBinDirs, namespace)
 		if err != nil {
-			return nil, re.ErrorCodePluginInitFailure.WithComponentType(re.Verifier).WithError(err)
+			return nil, re.ErrorCodePluginInitFailure.WithError(err)
 		}
 		verifiers = append(verifiers, verifier)
 	}
diff --git a/pkg/verifier/notation/certstoresbytype.go b/pkg/verifier/notation/certstoresbytype.go
index db9d37d..a5a9228 100644
--- a/pkg/verifier/notation/certstoresbytype.go
+++ b/pkg/verifier/notation/certstoresbytype.go
@@ -26,8 +26,9 @@ import (
 type certStoreType string
 
 const (
-	CA               certStoreType = "CA"
+	CA               certStoreType = "ca"
 	SigningAuthority certStoreType = "signingAuthority"
+	TSA              certStoreType = "tsa"
 )
 
 func (certstoretype certStoreType) String() string {
@@ -70,20 +71,20 @@ func newCertStoreByType(confInNewFormat verificationCertStores) (certStores, err
 	s := make(certStoresByType)
 	for certstoretype, storeData := range confInNewFormat {
 		s[certStoreType(certstoretype)] = make(map[string][]string)
-		parsedStoreData, ok := storeData.(verificationCertStores)
+		parsedStoreData, ok := storeData.(map[string]interface{})
 		if !ok {
-			return nil, fmt.Errorf("certStores: %s assertion to type verificationCertStores failed", storeData)
+			return nil, fmt.Errorf("the verificationCertStores configuration is invalid: %+v", confInNewFormat)
 		}
 		for storeName, certProviderList := range parsedStoreData {
 			var certProviderNames []string
 			parsedCertProviders, ok := certProviderList.([]interface{})
 			if !ok {
-				return nil, fmt.Errorf("certProviderList: %s assertion to type []interface{} failed", certProviderList)
+				return nil, fmt.Errorf("the verificationCertStores configuration is invalid: %+v", confInNewFormat)
 			}
 			for _, certProvider := range parsedCertProviders {
 				certProviderName, ok := certProvider.(string)
 				if !ok {
-					return nil, fmt.Errorf("certProvider: %s assertion to type string failed", certProvider)
+					return nil, fmt.Errorf("the verificationCertStores configuration is invalid: %+v", confInNewFormat)
 				}
 				certProviderNames = append(certProviderNames, certProviderName)
 			}
diff --git a/pkg/verifier/notation/notation.go b/pkg/verifier/notation/notation.go
index f9bc58d..f25b21c 100644
--- a/pkg/verifier/notation/notation.go
+++ b/pkg/verifier/notation/notation.go
@@ -50,6 +50,7 @@ const (
 	defaultCertPath                = "ratify-certs/notation/truststore"
 	trustStoreTypeCA               = string(truststore.TypeCA)
 	trustStoreTypeSigningAuthority = string(truststore.TypeSigningAuthority)
+	trustStoreTypeTSA              = string(truststore.TypeTSA)
 )
 
 // NotationPluginVerifierConfig describes the configuration of notation verifier
@@ -92,7 +93,7 @@ func init() {
 }
 
 func (f *notationPluginVerifierFactory) Create(_ string, verifierConfig config.VerifierConfig, pluginDirectory string, namespace string) (verifier.ReferenceVerifier, error) {
-	logger.GetLogger(context.Background(), logOpt).Debugf("creating notation with config %v, namespace '%v'", verifierConfig, namespace)
+	logger.GetLogger(context.Background(), logOpt).Debugf("creating Notation verifier with config %v, namespace '%v'", verifierConfig, namespace)
 	verifierName := fmt.Sprintf("%s", verifierConfig[types.Name])
 	verifierTypeStr := ""
 	if _, ok := verifierConfig[types.Type]; ok {
@@ -100,12 +101,12 @@ func (f *notationPluginVerifierFactory) Create(_ string, verifierConfig config.V
 	}
 	conf, err := parseVerifierConfig(verifierConfig, namespace)
 	if err != nil {
-		return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName)
+		return nil, re.ErrorCodePluginInitFailure.WithDetail("Failed to create the Notation Verifier").WithError(err)
 	}
 
 	verifyService, err := getVerifierService(conf, pluginDirectory)
 	if err != nil {
-		return nil, re.ErrorCodePluginInitFailure.WithComponentType(re.Verifier).WithPluginName(verifierName).WithError(err)
+		return nil, re.ErrorCodePluginInitFailure.WithDetail("Failed to create the Notation Verifier").WithError(err)
 	}
 
 	artifactTypes := strings.Split(conf.ArtifactTypes, ",")
@@ -142,22 +143,21 @@ func (v *notationPluginVerifier) Verify(ctx context.Context,
 
 	subjectDesc, err := store.GetSubjectDescriptor(ctx, subjectReference)
 	if err != nil {
-		return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeGetSubjectDescriptorFailure.NewError(re.ReferrerStore, store.Name(), re.EmptyLink, err, fmt.Sprintf("failed to resolve subject: %+v", subjectReference), re.HideStackTrace)
+		return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeVerifyReferenceFailure.WithDetail(fmt.Sprintf("Failed to validate the Notation signature of the artifact: %+v", subjectReference)).WithError(err)
 	}
 
 	referenceManifest, err := store.GetReferenceManifest(ctx, subjectReference, referenceDescriptor)
 	if err != nil {
-		return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeGetReferenceManifestFailure.NewError(re.ReferrerStore, store.Name(), re.EmptyLink, err, fmt.Sprintf("failed to resolve reference manifest: %+v", referenceDescriptor), re.HideStackTrace)
+		return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeVerifyReferenceFailure.WithDetail(fmt.Sprintf("Failed to validate the Notation signature: %+v", referenceDescriptor)).WithError(err)
 	}
 
 	if len(referenceManifest.Blobs) != 1 {
-		return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeVerifyPluginFailure.WithDetail(fmt.Sprintf("Notation signature manifest requires exactly one signature envelope blob, got %d", len(referenceManifest.Blobs))).WithRemediation(fmt.Sprintf("Please inspect the artifact [%s@%s] is correctly signed by Notation signer", subjectReference.Path, referenceDescriptor.Digest.String()))
+		return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeVerifyReferenceFailure.WithDetail(fmt.Sprintf("Notation signature manifest requires exactly one signature envelope blob, got %d", len(referenceManifest.Blobs))).WithRemediation(fmt.Sprintf("Please inspect the artifact [%s@%s] is correctly signed by Notation signer", subjectReference.Path, referenceDescriptor.Digest.String()))
 	}
-
 	blobDesc := referenceManifest.Blobs[0]
 	refBlob, err := store.GetBlobContent(ctx, subjectReference, blobDesc.Digest)
 	if err != nil {
-		return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeGetBlobContentFailure.NewError(re.ReferrerStore, store.Name(), re.EmptyLink, err, fmt.Sprintf("failed to get blob content of digest: %s", blobDesc.Digest), re.HideStackTrace)
+		return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeVerifyReferenceFailure.WithDetail(fmt.Sprintf("Failed to validate the Notation signature of the artifact: %+v", subjectReference)).WithError(err)
 	}
 
 	// TODO: notation verify API only accepts digested reference now.
@@ -165,7 +165,7 @@ func (v *notationPluginVerifier) Verify(ctx context.Context,
 	subjectRef := fmt.Sprintf("%s@%s", subjectReference.Path, subjectReference.Digest.String())
 	outcome, err := v.verifySignature(ctx, subjectRef, blobDesc.MediaType, subjectDesc.Descriptor, refBlob)
 	if err != nil {
-		return verifier.VerifierResult{IsSuccess: false, Extensions: extensions}, re.ErrorCodeVerifyPluginFailure.NewError(re.Verifier, v.name, re.NotationTsgLink, err, "failed to verify signature of digest", re.HideStackTrace)
+		return verifier.VerifierResult{IsSuccess: false, Extensions: extensions}, re.ErrorCodeVerifyReferenceFailure.WithDetail(fmt.Sprintf("Failed to validate the Notation signature: %+v", referenceDescriptor)).WithError(err)
 	}
 
 	// Note: notation verifier already validates certificate chain is not empty.
@@ -173,7 +173,7 @@ func (v *notationPluginVerifier) Verify(ctx context.Context,
 	extensions["Issuer"] = cert.Issuer.String()
 	extensions["SN"] = cert.Subject.String()
 
-	return verifier.NewVerifierResult("", v.name, v.verifierType, "Signature verification success", true, nil, extensions), nil
+	return verifier.NewVerifierResult("", v.name, v.verifierType, "Notation signature verification success", true, nil, extensions), nil
 }
 
 func getVerifierService(conf *NotationPluginVerifierConfig, pluginDirectory string) (notation.Verifier, error) {
@@ -181,7 +181,11 @@ func getVerifierService(conf *NotationPluginVerifierConfig, pluginDirectory stri
 	if err != nil {
 		return nil, err
 	}
-	return notationVerifier.New(&conf.TrustPolicyDoc, store, NewRatifyPluginManager(pluginDirectory))
+	verifier, err := notationVerifier.New(&conf.TrustPolicyDoc, store, NewRatifyPluginManager(pluginDirectory))
+	if err != nil {
+		return nil, re.ErrorCodePluginInitFailure.WithDetail("Failed to create the Notation Verifier").WithError(err)
+	}
+	return verifier, nil
 }
 
 func (v *notationPluginVerifier) verifySignature(ctx context.Context, subjectRef, mediaType string, subjectDesc oci.Descriptor, refBlob []byte) (*notation.VerificationOutcome, error) {
@@ -195,16 +199,15 @@ func (v *notationPluginVerifier) verifySignature(ctx context.Context, subjectRef
 }
 
 func parseVerifierConfig(verifierConfig config.VerifierConfig, _ string) (*NotationPluginVerifierConfig, error) {
-	verifierName := verifierConfig[types.Name].(string)
 	conf := &NotationPluginVerifierConfig{}
 
 	verifierConfigBytes, err := json.Marshal(verifierConfig)
 	if err != nil {
-		return nil, re.ErrorCodeConfigInvalid.NewError(re.Verifier, verifierName, re.EmptyLink, err, nil, re.HideStackTrace)
+		return nil, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("Failed to parse the Notation Verifier configuration: %+v", verifierConfig)).WithError(err)
 	}
 
 	if err := json.Unmarshal(verifierConfigBytes, &conf); err != nil {
-		return nil, re.ErrorCodeConfigInvalid.NewError(re.Verifier, verifierName, re.EmptyLink, err, fmt.Sprintf("failed to unmarshal to notationPluginVerifierConfig from: %+v.", verifierConfig), re.HideStackTrace)
+		return nil, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("Failed to parse the Notation Verifier configuration: %+v", verifierConfig)).WithError(err)
 	}
 
 	defaultCertsDir := paths.Join(homedir.Get(), ratifyconfig.ConfigFileDir, defaultCertPath)
@@ -226,7 +229,7 @@ func (v *notationPluginVerifier) GetNestedReferences() []string {
 func normalizeVerificationCertsStores(conf *NotationPluginVerifierConfig) error {
 	isCertStoresByType, isLegacyCertStore := false, false
 	for key := range conf.VerificationCertStores {
-		if key != trustStoreTypeCA && key != trustStoreTypeSigningAuthority {
+		if key != trustStoreTypeCA && key != trustStoreTypeSigningAuthority && key != trustStoreTypeTSA {
 			isLegacyCertStore = true
 			logger.GetLogger(context.Background(), logOpt).Debugf("Get VerificationCertStores in legacy format")
 		} else {
@@ -234,12 +237,30 @@ func normalizeVerificationCertsStores(conf *NotationPluginVerifierConfig) error
 		}
 	}
 	if isCertStoresByType && isLegacyCertStore {
-		return re.ErrorCodeConfigInvalid.NewError(re.Verifier, conf.Name, re.EmptyLink, nil, "both old VerificationCertStores and new VerificationCertStores are provided, please provide only one", re.HideStackTrace)
+		return re.ErrorCodeConfigInvalid.WithDetail("The verificationCertStores is misconfigured with both legacy and new formats").WithRemediation("Please provide only one format for the VerificationCertStores. Refer to the Notation Verifier configuration guide: https://ratify.dev/docs/plugins/verifier/notation#configuration")
 	} else if !isCertStoresByType && isLegacyCertStore {
+		legacyCertStore, err := normalizeLegacyCertStore(conf)
+		if err != nil {
+			return err
+		}
+		// support legacy verfier config format for backward compatibility
 		// normalize <store>:<certs> to ca:<store><certs> if no store type is provided
 		conf.VerificationCertStores = verificationCertStores{
-			trustStoreTypeCA: conf.VerificationCertStores,
+			trustStoreTypeCA: legacyCertStore,
 		}
 	}
 	return nil
 }
+
+// TODO: remove this function once the refactor is done [refactore tracking issue](https://github.com/ratify-project/ratify/issues/1752)
+func normalizeLegacyCertStore(conf *NotationPluginVerifierConfig) (map[string]interface{}, error) {
+	legacyCertStoreBytes, err := json.Marshal(conf.VerificationCertStores)
+	if err != nil {
+		return nil, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("Failed to recognize `verificationCertStores` value of Notation Verifier configuration: %+v", conf.VerificationCertStores)).WithError(err)
+	}
+	var legacyCertStore map[string]interface{}
+	if err := json.Unmarshal(legacyCertStoreBytes, &legacyCertStore); err != nil {
+		return nil, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("Failed to recognize `verificationCertStores` value of Notation Verifier configuration: %+v", conf.VerificationCertStores)).WithError(err)
+	}
+	return legacyCertStore, nil
+}
diff --git a/pkg/verifier/notation/pluginmanager.go b/pkg/verifier/notation/pluginmanager.go
index 32d7ddc..0ab8c4d 100644
--- a/pkg/verifier/notation/pluginmanager.go
+++ b/pkg/verifier/notation/pluginmanager.go
@@ -22,6 +22,7 @@ import (
 
 	"github.com/notaryproject/notation-go/dir"
 	"github.com/notaryproject/notation-go/plugin"
+	pl "github.com/notaryproject/notation-plugin-framework-go/plugin"
 )
 
 const (
@@ -39,7 +40,7 @@ func NewRatifyPluginManager(directory string) *RatifyPluginManager {
 }
 
 // Returns a notation Plugin for the given name if present in the target directory
-func (m *RatifyPluginManager) Get(ctx context.Context, name string) (plugin.Plugin, error) {
+func (m *RatifyPluginManager) Get(ctx context.Context, name string) (pl.Plugin, error) {
 	path, err := m.pluginFS.SysPath(notationPluginPrefix + name)
 	if err != nil {
 		return nil, err
diff --git a/pkg/verifier/notation/truststore.go b/pkg/verifier/notation/truststore.go
index c7bceb4..e9490cb 100644
--- a/pkg/verifier/notation/truststore.go
+++ b/pkg/verifier/notation/truststore.go
@@ -41,7 +41,7 @@ type trustStore struct {
 func newTrustStore(certPaths []string, verificationCertStores verificationCertStores) (*trustStore, error) {
 	certStores, err := newCertStoreByType(verificationCertStores)
 	if err != nil {
-		return nil, err
+		return nil, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("Failed to create the trust store from the verificationCertStores parameter in Notation Verifier configuration: %+v", verificationCertStores)).WithError(err).WithRemediation("Please check the value of the verificationCertStores parameter according to the Notation Verifier configuration guide: https://ratify.dev/docs/plugins/verifier/notation#configuration")
 	}
 	store := &trustStore{
 		certPaths:  certPaths,


Test patch:
diff --git a/cmd/ratify/cmd/cmd_test.go b/cmd/ratify/cmd/cmd_test.go
index 9016198..f2f1b28 100644
--- a/cmd/ratify/cmd/cmd_test.go
+++ b/cmd/ratify/cmd/cmd_test.go
@@ -36,8 +36,8 @@ func TestVerify(t *testing.T) {
 
 	// TODO: make ratify cli more unit testable
 	// unit test should not have dependency for real image
-	if !strings.Contains(err.Error(), "plugin not found") {
-		t.Errorf("error expected")
+	if !strings.Contains(err.Error(), "PLUGIN_NOT_FOUND") {
+		t.Fatalf("expected containing: %s, but got: %s", "PLUGIN_NOT_FOUND", err.Error())
 	}
 }
 
diff --git a/pkg/controllers/clusterresource/verifier_controller_test.go b/pkg/controllers/clusterresource/verifier_controller_test.go
index 850a1fb..96cfb59 100644
--- a/pkg/controllers/clusterresource/verifier_controller_test.go
+++ b/pkg/controllers/clusterresource/verifier_controller_test.go
@@ -19,7 +19,6 @@ import (
 	"context"
 	"errors"
 	"os"
-	"strings"
 	"testing"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
@@ -124,12 +123,12 @@ func TestVerifierAdd_WithParameters(t *testing.T) {
 
 func TestVerifierAddOrReplace_PluginNotFound(t *testing.T) {
 	resetVerifierMap()
-	var resource = "invalidplugin"
-	expectedMsg := "plugin not found"
+	resource := "invalidplugin"
+	expectedMsg := "PLUGIN_NOT_FOUND: Verifier plugin pluginnotfound not found: failed to find plugin \"pluginnotfound\" in paths [test/path]: Please ensure that the correct type is specified for the built-in Verifier configuration or the custom Verifier plugin is configured."
 	var testVerifierSpec = getInvalidVerifierSpec()
 	err := verifierAddOrReplace(testVerifierSpec, resource)
 
-	if !strings.Contains(err.Error(), expectedMsg) {
+	if err.Error() != expectedMsg {
 		t.Fatalf("TestVerifierAddOrReplace_PluginNotFound expected msg: '%v', actual %v", expectedMsg, err.Error())
 	}
 }
diff --git a/pkg/controllers/namespaceresource/verifier_controller_test.go b/pkg/controllers/namespaceresource/verifier_controller_test.go
index ac433a5..5c65f16 100644
--- a/pkg/controllers/namespaceresource/verifier_controller_test.go
+++ b/pkg/controllers/namespaceresource/verifier_controller_test.go
@@ -19,7 +19,6 @@ import (
 	"context"
 	"errors"
 	"os"
-	"strings"
 	"testing"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
@@ -142,12 +141,12 @@ func TestVerifierAdd_WithParameters(t *testing.T) {
 
 func TestVerifierAddOrReplace_PluginNotFound(t *testing.T) {
 	resetVerifierMap()
-	var resource = "invalidplugin"
-	expectedMsg := "plugin not found"
+	resource := "invalidplugin"
+	expectedMsg := "PLUGIN_NOT_FOUND: Verifier plugin pluginnotfound not found: failed to find plugin \"pluginnotfound\" in paths [test/path]: Please ensure that the correct type is specified for the built-in Verifier configuration or the custom Verifier plugin is configured."
 	var testVerifierSpec = getInvalidVerifierSpec()
 	err := verifierAddOrReplace(testVerifierSpec, resource, testNamespace)
 
-	if !strings.Contains(err.Error(), expectedMsg) {
+	if err.Error() != expectedMsg {
 		t.Fatalf("TestVerifierAddOrReplace_PluginNotFound expected msg: '%v', actual %v", expectedMsg, err.Error())
 	}
 }
diff --git a/pkg/verifier/factory/factory_test.go b/pkg/verifier/factory/factory_test.go
index 273e76b..7b839e0 100644
--- a/pkg/verifier/factory/factory_test.go
+++ b/pkg/verifier/factory/factory_test.go
@@ -22,6 +22,7 @@ import (
 
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/common"
+	"github.com/ratify-project/ratify/pkg/featureflag"
 	"github.com/ratify-project/ratify/pkg/ocispecs"
 	"github.com/ratify-project/ratify/pkg/referrerstore"
 
@@ -103,6 +104,21 @@ func TestCreateVerifiersFromConfig_BuiltInVerifiers_ReturnsExpected(t *testing.T
 	}
 }
 
+func TestCreateVerifiersFromConfig_InvalidConfig_ReturnsErr(t *testing.T) {
+	verifierConfig := map[string]interface{}{
+		"name": "test-verifier-0",
+	}
+	verifiersConfig := config.VerifiersConfig{
+		Verifiers: []config.VerifierConfig{verifierConfig},
+	}
+
+	_, err := CreateVerifiersFromConfig(verifiersConfig, "test/dir", constants.EmptyNamespace)
+
+	if err == nil {
+		t.Fatalf("expected to have an error")
+	}
+}
+
 func TestCreateVerifiersFromConfig_PluginVerifiers_ReturnsExpected(t *testing.T) {
 	dirPath, err := utils.CreatePlugin("sample")
 	if err != nil {
@@ -137,3 +153,83 @@ func TestCreateVerifiersFromConfig_PluginVerifiers_ReturnsExpected(t *testing.T)
 		t.Fatalf("type assertion failed expected a plugin in verifier")
 	}
 }
+
+func TestCreateVerifiersFromConfig_EmptyVerifiers_ReturnsErr(t *testing.T) {
+	verifiersConfig := config.VerifiersConfig{}
+
+	_, err := CreateVerifiersFromConfig(verifiersConfig, "test/dir", "")
+
+	if err == nil {
+		t.Fatalf("expected to have an error")
+	}
+}
+
+func TestCreateVerifierFromConfig(t *testing.T) {
+	tests := []struct {
+		name                 string
+		verifierConfig       config.VerifierConfig
+		configVersion        string
+		pluginBinDir         []string
+		namespace            string
+		dynamicPluginEnabled bool
+		expectedErr          bool
+	}{
+		{
+			name:           "missing name",
+			verifierConfig: config.VerifierConfig{},
+			expectedErr:    true,
+		},
+		{
+			name: "verifier type contains path separator",
+			verifierConfig: config.VerifierConfig{
+				"name": "test/verifier",
+			},
+			expectedErr: true,
+		},
+		{
+			name: "external verifier plugin not found",
+			verifierConfig: config.VerifierConfig{
+				"name": "not-found",
+			},
+			pluginBinDir: []string{"test/path"},
+			expectedErr:  true,
+		},
+		{
+			name: "parse plugin source failed",
+			verifierConfig: config.VerifierConfig{
+				"name":   "test-verifier",
+				"source": "invalid",
+			},
+			dynamicPluginEnabled: true,
+			expectedErr:          true,
+		},
+		{
+			name: "download plugin failed",
+			verifierConfig: config.VerifierConfig{
+				"name": "test-verifier",
+				"source": map[string]interface{}{
+					"artifact": "invalid",
+				},
+			},
+			pluginBinDir:         []string{"test/path"},
+			dynamicPluginEnabled: true,
+			expectedErr:          true,
+		},
+	}
+
+	for _, tt := range tests {
+		tt := tt
+		t.Run(tt.name, func(t *testing.T) {
+			if tt.dynamicPluginEnabled {
+				dynamicVal := featureflag.DynamicPlugins.Enabled
+				t.Cleanup(func() { featureflag.DynamicPlugins.Enabled = dynamicVal })
+				featureflag.DynamicPlugins.Enabled = true
+			}
+
+			_, err := CreateVerifierFromConfig(tt.verifierConfig, tt.configVersion, tt.pluginBinDir, tt.namespace)
+			if tt.expectedErr != (err != nil) {
+				t.Fatalf("expected error %v, actual %v", tt.expectedErr, err)
+			}
+		})
+	}
+}
diff --git a/pkg/verifier/notation/certstoresbytype_test.go b/pkg/verifier/notation/certstoresbytype_test.go
index dc3d0da..cd4ae90 100644
--- a/pkg/verifier/notation/certstoresbytype_test.go
+++ b/pkg/verifier/notation/certstoresbytype_test.go
@@ -33,7 +33,7 @@ func TestNewCertStoreByTypeInvalidInput(t *testing.T) {
 		{
 			name: "invalid certProviderList type",
 			conf: verificationCertStores{
-				trustStoreTypeCA: verificationCertStores{
+				trustStoreTypeCA: map[string]interface{}{
 					"certstore1": "akv1",
 					"certstore2": []interface{}{"akv3", "akv4"},
 				},
@@ -43,7 +43,7 @@ func TestNewCertStoreByTypeInvalidInput(t *testing.T) {
 		{
 			name: "invalid certProvider type",
 			conf: verificationCertStores{
-				trustStoreTypeCA: verificationCertStores{
+				trustStoreTypeCA: map[string]interface{}{
 					"certstore1": []interface{}{"akv1", []string{}},
 				},
 			},
diff --git a/pkg/verifier/notation/notation_test.go b/pkg/verifier/notation/notation_test.go
index 3bbebe0..dc34a1f 100644
--- a/pkg/verifier/notation/notation_test.go
+++ b/pkg/verifier/notation/notation_test.go
@@ -71,6 +71,10 @@ var (
 	}
 	invalidRef = common.Reference{
 		Original: "invalid",
+		Tag:      "invalid",
+	}
+	invalidRef2 = common.Reference{
+		Original: "invalid",
 	}
 	testNotationPluginVerifier notation.Verifier = mockNotationPluginVerifier{}
 	validBlobDesc                                = ocispec.Descriptor{
@@ -136,7 +140,10 @@ func (s mockStore) GetConfig() *config.StoreConfig {
 	return nil
 }
 
-func (s mockStore) GetSubjectDescriptor(_ context.Context, _ common.Reference) (*ocispecs.SubjectDescriptor, error) {
+func (s mockStore) GetSubjectDescriptor(_ context.Context, subjectReference common.Reference) (*ocispecs.SubjectDescriptor, error) {
+	if subjectReference.Tag == "invalid" {
+		return nil, fmt.Errorf("cannot resolve digest for the subject reference")
+	}
 	return &ocispecs.SubjectDescriptor{
 		Descriptor: ocispec.Descriptor{},
 	}, nil
@@ -214,7 +221,22 @@ func TestParseVerifierConfig(t *testing.T) {
 			name: "failed unmarshalling to notation config",
 			configMap: map[string]interface{}{
 				"name":              test,
-				"verificationCerts": test,
+				"verificationCerts": make(chan int),
+			},
+			expectErr: true,
+			expect:    nil,
+		},
+		{
+			name: "failed unmarshalling to notation config",
+			configMap: map[string]interface{}{
+				"name": test,
+				"verificationCertStores": verificationCertStores{
+					"certstore1": []interface{}{"akv1", "akv2"},
+					"ca": map[string]interface{}{
+						"certstore1": []interface{}{"akv1", "akv2"},
+						"certstore2": []interface{}{"akv3", "akv4"},
+					},
+				},
 			},
 			expectErr: true,
 			expect:    nil,
@@ -257,7 +279,7 @@ func TestParseVerifierConfig(t *testing.T) {
 				Name:              test,
 				VerificationCerts: []string{testPath, defaultCertDir},
 				VerificationCertStores: verificationCertStores{
-					trustStoreTypeCA: verificationCertStores{
+					trustStoreTypeCA: map[string]interface{}{
 						"certstore1": []interface{}{"akv1", "akv2"},
 						"certstore2": []interface{}{"akv3", "akv4"},
 					},
@@ -302,6 +324,18 @@ func TestCreate(t *testing.T) {
 		expect    verifier.ReferenceVerifier
 		expectErr bool
 	}{
+		{
+			name: "failed get verify service",
+			configMap: map[string]interface{}{
+				"name": test,
+				"verificationCertStores": verificationCertStores{
+					trustStoreTypeCA: verificationCertStores{
+						"certstore1": []interface{}{"akv1", "akv2", 1},
+					},
+				},
+			},
+			expectErr: true,
+		},
 		{
 			name: "failed parsing verifier config",
 			configMap: map[string]interface{}{
@@ -350,13 +384,21 @@ func TestVerify(t *testing.T) {
 		expectErr bool
 	}{
 		{
-			name:      "failed getting manifest",
+			name:      "failed getting subject descriptor",
 			ref:       invalidRef,
 			refBlob:   []byte(""),
 			manifest:  ocispecs.ReferenceManifest{},
 			expect:    failedResult,
 			expectErr: true,
 		},
+		{
+			name:      "failed getting manifest",
+			ref:       invalidRef2,
+			refBlob:   []byte(""),
+			manifest:  ocispecs.ReferenceManifest{},
+			expect:    failedResult,
+			expectErr: true,
+		},
 		{
 			name:    "failed verifying signature",
 			ref:     validRef2,
@@ -438,18 +480,15 @@ func TestNormalizeVerificationCertsStores(t *testing.T) {
 		expectErr bool
 	}{
 		{
-			name: "successfully normalizaVerificationCertsStores",
+			name: "failed normalizaVerificationCertsStores in marshal function",
 			conf: &NotationPluginVerifierConfig{
 				Name:              test,
 				VerificationCerts: []string{testPath, defaultCertDir},
 				VerificationCertStores: verificationCertStores{
-					trustStoreTypeCA: verificationCertStores{
-						"certstore1": []interface{}{"akv1", "akv2"},
-						"certstore2": []interface{}{"akv3", "akv4"},
-					},
+					"certstore2": []interface{}{make(chan int)},
 				},
 			},
-			expectErr: false,
+			expectErr: true,
 		},
 		{
 
@@ -458,7 +497,7 @@ func TestNormalizeVerificationCertsStores(t *testing.T) {
 				Name:              test,
 				VerificationCerts: []string{testPath, defaultCertDir},
 				VerificationCertStores: verificationCertStores{
-					trustStoreTypeCA: verificationCertStores{
+					trustStoreTypeCA: map[string]interface{}{
 						"certstore1": []interface{}{"akv1", "akv2"},
 					},
 					"certstore2": []interface{}{"akv3", "akv4"},
@@ -466,6 +505,20 @@ func TestNormalizeVerificationCertsStores(t *testing.T) {
 			},
 			expectErr: true,
 		},
+		{
+			name: "successfully normalizaVerificationCertsStores",
+			conf: &NotationPluginVerifierConfig{
+				Name:              test,
+				VerificationCerts: []string{testPath, defaultCertDir},
+				VerificationCertStores: verificationCertStores{
+					trustStoreTypeCA: map[string]interface{}{
+						"certstore1": []interface{}{"akv1", "akv2"},
+						"certstore2": []interface{}{"akv3", "akv4"},
+					},
+				},
+			},
+			expectErr: false,
+		},
 	}
 
 	for _, tt := range tests {
@@ -477,3 +530,31 @@ func TestNormalizeVerificationCertsStores(t *testing.T) {
 		})
 	}
 }
+
+func TestNormalizeLegacyCertStore(t *testing.T) {
+	tests := []struct {
+		name      string
+		conf      *NotationPluginVerifierConfig
+		expectErr bool
+	}{
+		{
+			name: "successfully normalizaVerificationCertsStores",
+			conf: &NotationPluginVerifierConfig{
+				Name:              test,
+				VerificationCerts: []string{testPath, defaultCertDir},
+				VerificationCertStores: verificationCertStores{
+					"certstore2": []interface{}{make(chan int)},
+				},
+			},
+			expectErr: true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			_, err := normalizeLegacyCertStore(tt.conf)
+			if (err != nil) != tt.expectErr {
+				t.Errorf("error = %v, expectErr = %v", err, tt.expectErr)
+			}
+		})
+	}
+}
diff --git a/pkg/verifier/notation/truststore_test.go b/pkg/verifier/notation/truststore_test.go
index 393103a..eb64c04 100644
--- a/pkg/verifier/notation/truststore_test.go
+++ b/pkg/verifier/notation/truststore_test.go
@@ -109,7 +109,7 @@ func TestParseErrFromKmpAndCertStore(t *testing.T) {
 func TestGetCertificates_EmptyCertMap(t *testing.T) {
 	resetCertStore()
 	certStore := verificationCertStores{
-		trustStoreTypeCA: verificationCertStores{
+		trustStoreTypeCA: map[string]interface{}{
 			"certstore1": []interface{}{"akv1", "akv2"},
 			"certstore2": []interface{}{"akv3", "akv4"},
 		},
@@ -126,7 +126,7 @@ func TestGetCertificates_EmptyCertMap(t *testing.T) {
 func TestGetCertificates_ErrorFromKMPReconcile(t *testing.T) {
 	resetCertStore()
 	certStore := verificationCertStores{
-		trustStoreTypeCA: verificationCertStores{
+		trustStoreTypeCA: map[string]interface{}{
 			"certstore1": []interface{}{"default/kv1"},
 			"certstore2": []interface{}{"projecta/kv2"},
 		},
@@ -149,7 +149,7 @@ func TestGetCertificates_ErrorFromKMPReconcile(t *testing.T) {
 func TestGetCertificates_NamedStore(t *testing.T) {
 	resetCertStore()
 	certStore := verificationCertStores{
-		trustStoreTypeCA: verificationCertStores{
+		trustStoreTypeCA: map[string]interface{}{
 			"certstore1": []interface{}{"default/kv1"},
 			"certstore2": []interface{}{"projecta/kv2"},
 		},
diff --git a/scripts/azure-ci-test.sh b/scripts/azure-ci-test.sh
index 1589ade..c5c7be9 100755
--- a/scripts/azure-ci-test.sh
+++ b/scripts/azure-ci-test.sh
@@ -142,7 +142,7 @@ trap cleanup EXIT
 main() {
   ./scripts/create-azure-resources.sh
   create_key_akv
-  
+
   local ACR_USER_NAME="00000000-0000-0000-0000-000000000000"
   local ACR_PASSWORD=$(az acr login --name ${ACR_NAME} --expose-token --output tsv --query accessToken)
   make e2e-azure-setup TEST_REGISTRY=$REGISTRY TEST_REGISTRY_USERNAME=${ACR_USER_NAME} TEST_REGISTRY_PASSWORD=${ACR_PASSWORD} KEYVAULT_KEY_NAME=${KEYVAULT_KEY_NAME} KEYVAULT_NAME=${KEYVAULT_NAME}
@@ -152,7 +152,9 @@ main() {
   deploy_gatekeeper
   deploy_ratify
 
-  TEST_REGISTRY=$REGISTRY bats -t ./test/bats/azure-test.bats
+  local IDENTITY_CLIENT_ID=$(az identity show --name ${USER_ASSIGNED_IDENTITY_NAME} --resource-group ${GROUP_NAME} --query 'clientId' -o tsv)
+  local VAULT_URI=$(az keyvault show --name ${KEYVAULT_NAME} --resource-group ${GROUP_NAME} --query "properties.vaultUri" -otsv)
+  TEST_REGISTRY=$REGISTRY IDENTITY_CLIENT_ID=$IDENTITY_CLIENT_ID VAULT_URI=$VAULT_URI bats -t ./test/bats/azure-test.bats
 }
 
 main
diff --git a/test/bats/azure-test.bats b/test/bats/azure-test.bats
index a30556d..d37a8f5 100644
--- a/test/bats/azure-test.bats
+++ b/test/bats/azure-test.bats
@@ -70,7 +70,7 @@ SLEEP_TIME=1
     sed -i '10,$d' ./test/bats/tests/config/config_v1beta1_keymanagementprovider_inline.yaml
 
     # configure the notation verifier to use the inline key management provider
-    run kubectl apply -f ./test/bats/tests/config/config_v1beta1_verifier_notation_kmprovider.yaml
+    run kubectl replace -f ./test/bats/tests/config/config_v1beta1_verifier_notation_kmprovider.yaml
     assert_success
 
     # wait for the httpserver cache to be invalidated
@@ -318,3 +318,80 @@ SLEEP_TIME=1
     result=$(kubectl get pod mutate-demo --namespace default -o json | jq -r ".spec.containers[0].image" | grep @sha)
     assert_mutate_success
 }
+
+@test "validate refresher reconcile count" {
+    teardown() {
+        echo "cleaning up"
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete keymanagementprovider kmp-akv-refresh --ignore-not-found=true'
+        rm test.yaml
+    }
+    sed -e "s/keymanagementprovider-akv/kmp-akv-refresh/" \
+        -e "s/1m/1s/" \
+        -e "s/yourCertName/${NOTATION_PEM_NAME}/" \
+        -e '/version: yourCertVersion/d' \
+        -e "s|https://yourkeyvault.vault.azure.net/|${VAULT_URI}|" \
+        -e "s/tenantID:/tenantID: ${TENANT_ID}/" \
+        -e "s/clientID:/clientID: ${IDENTITY_CLIENT_ID}/" \
+        ./config/samples/clustered/kmp/config_v1beta1_keymanagementprovider_akv_refresh_enabled.yaml >test.yaml
+    run kubectl apply -f test.yaml
+    assert_success
+    sleep 10
+    count=$(kubectl logs deployment/ratify -n gatekeeper-system | grep "Reconciled KeyManagementProvider" | wc -l)
+    [ $count -ge 4 ]
+}
+
+@test "validate refresher updates kmp with latest certificate version" {
+    teardown() {
+        echo "cleaning up"
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete keymanagementprovider kmp-akv-refresh --ignore-not-found=true'
+        rm test.yaml
+        rm policy.json
+    }
+    sed -e "s/keymanagementprovider-akv/kmp-akv-refresh/" \
+        -e "s/1m/5s/" \
+        -e "s/yourCertName/${NOTATION_PEM_NAME}/" \
+        -e '/version: yourCertVersion/d' \
+        -e "s|https://yourkeyvault.vault.azure.net/|${VAULT_URI}|" \
+        -e "s/tenantID:/tenantID: ${TENANT_ID}/" \
+        -e "s/clientID:/clientID: ${IDENTITY_CLIENT_ID}/" \
+        ./config/samples/clustered/kmp/config_v1beta1_keymanagementprovider_akv_refresh_enabled.yaml >test.yaml
+    run kubectl apply -f test.yaml
+    assert_success
+    sleep 5
+    result=$(kubectl get keymanagementprovider kmp-akv-refresh -o jsonpath='{.status.properties.Certificates[0].Version}')
+    az keyvault certificate get-default-policy -o json >>policy.json
+    wait_for_process 20 10 "az keyvault certificate create --vault-name $KEYVAULT_NAME --name $NOTATION_PEM_NAME --policy @policy.json"
+    sleep 30
+    refreshResult=$(kubectl get keymanagementprovider kmp-akv-refresh -o jsonpath='{.status.properties.Certificates[0].Version}')
+    [ "$result" != "$refreshResult" ]
+}
+
+@test "validate certificate specified version" {
+    teardown() {
+        echo "cleaning up"
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete keymanagementprovider kmp-akv-refresh --ignore-not-found=true'
+        rm policy.json
+        rm test.yaml
+    }
+    sed -e "s/keymanagementprovider-akv/kmp-akv-refresh/" \
+        -e "s/1m/1s/" \
+        -e "s/yourCertName/${NOTATION_PEM_NAME}/" \
+        -e '/version: yourCertVersion/d' \
+        -e "s|https://yourkeyvault.vault.azure.net/|${VAULT_URI}|" \
+        -e "s/tenantID:/tenantID: ${TENANT_ID}/" \
+        -e "s/clientID:/clientID: ${IDENTITY_CLIENT_ID}/" \
+        ./config/samples/clustered/kmp/config_v1beta1_keymanagementprovider_akv_refresh_enabled.yaml >test.yaml
+    version=$(az keyvault certificate show --vault-name $KEYVAULT_NAME --name $NOTATION_PEM_NAME --query 'sid' -o tsv | rev | cut -d'/' -f1 | rev)
+    sed -i \
+        -e "/name: ${NOTATION_PEM_NAME}/a \ \ \ \ \ \ \ \ version: ${version}" \
+        test.yaml
+    run kubectl apply -f test.yaml
+    assert_success
+    sleep 10
+    result=$(kubectl get keymanagementprovider kmp-akv-refresh -o jsonpath='{.status.properties.Certificates[0].Version}')
+    az keyvault certificate get-default-policy -o json >>policy.json
+    wait_for_process 20 10 "az keyvault certificate create --vault-name $KEYVAULT_NAME --name $NOTATION_PEM_NAME --policy @policy.json"
+    sleep 30
+    refreshResult=$(kubectl get keymanagementprovider kmp-akv-refresh -o jsonpath='{.status.properties.Certificates[0].Version}')
+    [ "$result" = "$refreshResult" ]
+}
diff --git a/test/bats/base-test.bats b/test/bats/base-test.bats
index ca54ef3..bc30766 100644
--- a/test/bats/base-test.bats
+++ b/test/bats/base-test.bats
@@ -96,6 +96,35 @@ RATIFY_NAMESPACE=gatekeeper-system
     assert_failure
 }
 
+@test "notation test timestamping" {
+    teardown() {
+        echo "cleaning up"
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete pod demo-tsa --namespace default --force --ignore-not-found=true'
+
+        # restore the original notation verifier for other tests
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl replace -f ./config/samples/clustered/verifier/config_v1beta1_verifier_notation.yaml'
+    }
+
+    # validate key management provider status property shows success
+    run bash -c "kubectl get keymanagementproviders.config.ratify.deislabs.io/ratify-notation-inline-cert-0 -o yaml | grep 'issuccess: true'"
+    assert_success
+
+    # add the tsaroot certificate as an inline key management provider
+    cat ./test/bats/tests/config/config_v1beta1_keymanagementprovider_inline.yaml >> tsakmprovider.yaml
+    cat ./test/bats/tests/certificates/tsarootca.cer | sed 's/^/      /g' >> tsakmprovider.yaml
+    run kubectl apply -f tsakmprovider.yaml --namespace ${RATIFY_NAMESPACE}
+    assert_success
+
+    # configure the notation verifier to use the inline key management provider
+    run kubectl replace -f ./test/bats/tests/config/config_v1beta1_verifier_notation_tsa.yaml
+    assert_success
+    sleep 10
+
+    # verify that the image can now be run
+    run kubectl run demo-tsa --namespace default --image=registry:5000/notation:tsa
+    assert_success
+}
+
 @test "notation test with certs across namespace" {
     teardown() {
         echo "cleaning up"
diff --git a/test/bats/cli-test.bats b/test/bats/cli-test.bats
index ae8f78d..abbe8e2 100644
--- a/test/bats/cli-test.bats
+++ b/test/bats/cli-test.bats
@@ -21,6 +21,9 @@ load helpers
 
     run bin/ratify verify -c $RATIFY_DIR/config.json -s $TEST_REGISTRY/notation:unsigned
     assert_cmd_verify_failure
+
+    run bin/ratify verify -c $RATIFY_DIR/config_tsa.json -s $TEST_REGISTRY/notation:tsa
+    assert_cmd_verify_success
 }
 
 @test "notation verifier leaf cert test" {
@@ -142,3 +145,19 @@ load helpers
     test -x $RATIFY_DIR/plugins/dynamicstore
     assert_success
 }
+
+@test "notation verifier tsa test" {
+    teardown() {
+        # reset current_time
+        run sudo date -s "-2 days"
+    }
+
+    # update system date to expire the cert and trigger timestamp verification
+    run sudo date -s "2 days" 
+
+    run bin/ratify verify -c $RATIFY_DIR/config.json -s $TEST_REGISTRY/notation:tsa
+    assert_cmd_verify_failure
+
+    run bin/ratify verify -c $RATIFY_DIR/config_tsa.json -s $TEST_REGISTRY/notation:tsa
+    assert_cmd_verify_success
+}
\ No newline at end of file
diff --git a/test/bats/tests/certificates/tsarootca.cer b/test/bats/tests/certificates/tsarootca.cer
new file mode 100644
index 0000000..1a1e4fb
--- /dev/null
+++ b/test/bats/tests/certificates/tsarootca.cer
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
+RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
+ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
+xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
+ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
+DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
+jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
+CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
+EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
+fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
+uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
+chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
+9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
+SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
+fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
+sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
+cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
+0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
+4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
+r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
+/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
+gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+-----END CERTIFICATE-----
diff --git a/test/bats/tests/config/config_tsa.json b/test/bats/tests/config/config_tsa.json
new file mode 100644
index 0000000..e3791df
--- /dev/null
+++ b/test/bats/tests/config/config_tsa.json
@@ -0,0 +1,101 @@
+{
+    "store": {
+        "version": "1.0.0",
+        "plugins": [
+            {
+                "name": "oras",
+                "cosignEnabled": true,
+                "useHttp": true
+            }
+        ]
+    },
+    "policy": {
+        "version": "1.0.0",
+        "plugin": {
+            "name": "configPolicy"
+        }
+    },
+    "verifier": {
+        "version": "1.0.0",
+        "plugins": [
+            {
+                "name": "schemavalidator",
+                "artifactTypes": "application/vnd.aquasecurity.trivy.report.sarif.v1",
+                "schemas": {
+                    "application/sarif+json": "file:///home/runner/.ratify/schemas/sarif-2.1.0-rtm.5.json"
+                }
+            },
+            {
+                "name": "sbom",
+                "artifactTypes": "application/spdx+json",
+                "nestedReferences": "application/vnd.cncf.notary.signature",
+                "disallowedLicenses":["AGPL"],
+                "disallowedPackages":[{"name":"log4j-core","versionInfo":"2.13.0"}]
+            
+            },
+            {
+                "name": "cosign",
+                "artifactTypes": "application/vnd.dev.cosign.artifact.sig.v1+json",
+                "key": ".staging/cosign/cosign.pub"
+            },
+            {
+                "name": "notation",
+                "artifactTypes": "application/vnd.cncf.notary.signature",
+                "verificationCerts": [
+                    "~/.config/notation/localkeys/ratify-bats-test.crt",
+                    "~/.ratify/ratify-certs/notation/tsarootca.cer"
+                ],
+                "trustPolicyDoc": {
+                    "version": "1.0",
+                    "trustPolicies": [
+                        {
+                            "name": "default",
+                            "registryScopes": [
+                                "*"
+                            ],
+                            "signatureVerification": {
+                                "level": "strict",
+                                "verifyTimestamp": "afterCertExpiry"
+                            },
+                            "trustStores": [
+                                "ca:ca-certs",
+                                "tsa:tsa-certs"
+                            ],
+                            "trustedIdentities": [
+                                "*"
+                            ]
+                        }
+                    ]
+                }
+            },
+            {
+                "name": "schemavalidator",
+                "artifactTypes": "application/vnd.aquasecurity.trivy.report.sarif.v1",
+                "schemas": {
+                    "application/sarif+json": "https://json.schemastore.org/sarif-2.1.0-rtm.5.json"
+                }
+            },
+            {
+                "name": "licensechecker",
+                "artifactTypes": "application/vnd.ratify.spdx.v0",
+                "allowedLicenses": [
+                    "GPL-2.0-only",
+                    "MIT",
+                    "OpenSSL",
+                    "BSD-2-Clause AND BSD-3-Clause",
+                    "Zlib",
+                    "MPL-2.0 AND MIT",
+                    "ISC",
+                    "Apache-2.0",
+                    "MIT AND BSD-2-Clause AND GPL-2.0-or-later",
+                    "MIT AND LicenseRef-AND AND BSD-2-Clause AND LicenseRef-AND AND GPL-2.0-or-later",
+                    "MPL-2.0 AND LicenseRef-AND AND MIT",
+                    "BSD-2-Clause AND LicenseRef-AND AND BSD-3-Clause",
+                    "NONE",
+                    "NOASSERTION",
+                    ""
+                ]
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/test/bats/tests/config/config_v1beta1_verifier_notation.yaml b/test/bats/tests/config/config_v1beta1_verifier_notation.yaml
index fb6595d..bb1564a 100644
--- a/test/bats/tests/config/config_v1beta1_verifier_notation.yaml
+++ b/test/bats/tests/config/config_v1beta1_verifier_notation.yaml
@@ -7,7 +7,8 @@ spec:
   artifactTypes: application/vnd.cncf.notary.signature
   parameters:
     verificationCertStores:
-      certs:
+      ca:
+        ca-certs:
         - certstore-inline
     trustPolicyDoc:
       version: "1.0"
@@ -18,6 +19,6 @@ spec:
           signatureVerification:
             level: strict
           trustStores:
-            - ca:certs
+            - ca:ca-certs
           trustedIdentities:
             - "*"
diff --git a/test/bats/tests/config/config_v1beta1_verifier_notation_akv.yaml b/test/bats/tests/config/config_v1beta1_verifier_notation_akv.yaml
index 0311802..ea2d24c 100644
--- a/test/bats/tests/config/config_v1beta1_verifier_notation_akv.yaml
+++ b/test/bats/tests/config/config_v1beta1_verifier_notation_akv.yaml
@@ -7,8 +7,9 @@ spec:
   artifactTypes: application/vnd.cncf.notary.signature
   parameters:
     verificationCertStores:
-      certs:
-        - kmprovider-akv
+      ca:
+        ca-certs:
+          - kmprovider-akv
     trustPolicyDoc:
       version: "1.0"
       trustPolicies:
@@ -18,6 +19,6 @@ spec:
           signatureVerification:
             level: strict
           trustStores:
-            - ca:certs
+            - ca:ca-certs
           trustedIdentities:
             - "*"
diff --git a/test/bats/tests/config/config_v1beta1_verifier_notation_kmprovider.yaml b/test/bats/tests/config/config_v1beta1_verifier_notation_kmprovider.yaml
index c90ccc5..04304c3 100644
--- a/test/bats/tests/config/config_v1beta1_verifier_notation_kmprovider.yaml
+++ b/test/bats/tests/config/config_v1beta1_verifier_notation_kmprovider.yaml
@@ -7,8 +7,9 @@ spec:
   artifactTypes: application/vnd.cncf.notary.signature
   parameters:
     verificationCertStores:
-      certs:
-        - keymanagementprovider-inline
+      ca:
+        ca-certs:
+          - keymanagementprovider-inline
     trustPolicyDoc:
       version: "1.0"
       trustPolicies:
@@ -18,6 +19,6 @@ spec:
           signatureVerification:
             level: strict
           trustStores:
-            - ca:certs
+            - ca:ca-certs
           trustedIdentities:
             - "*"
diff --git a/test/bats/tests/config/config_v1beta1_verifier_notation_tsa.yaml b/test/bats/tests/config/config_v1beta1_verifier_notation_tsa.yaml
new file mode 100644
index 0000000..46d8048
--- /dev/null
+++ b/test/bats/tests/config/config_v1beta1_verifier_notation_tsa.yaml
@@ -0,0 +1,28 @@
+apiVersion: config.ratify.deislabs.io/v1beta1
+kind: Verifier
+metadata:
+  name: verifier-notation
+spec:
+  name: notation
+  artifactTypes: application/vnd.cncf.notary.signature
+  parameters:
+    verificationCertStores:
+      ca:
+        ca-certs:
+          - ratify-notation-inline-cert-0
+      tsa:
+        tsa-certs:
+          - keymanagementprovider-inline
+    trustPolicyDoc:
+      version: "1.0"
+      trustPolicies:
+        - name: default
+          registryScopes:
+            - "*"
+          signatureVerification:
+            level: strict
+          trustStores:
+            - ca:ca-certs
+            - tsa:tsa-certs
+          trustedIdentities:
+            - "*"
diff --git a/test/validation.md b/test/validation.md
index 7e17a0c..e659ae9 100644
--- a/test/validation.md
+++ b/test/validation.md
@@ -12,6 +12,7 @@ While we are working on improving our coverage, here is the list of scenarios th
 ### CLI
 - Verifier Scenarios
     - Notation
+        - TSA
     - Cosign
         - Keyed
         - Keyless 
@@ -25,6 +26,7 @@ While we are working on improving our coverage, here is the list of scenarios th
 ### Kubernetes
 - Verifier Scenarios
     - Notation
+        - TSA
     - Cosign
     - SBOM
     - License Checker