Repository: ratify-project/ratify
Pull request #1761 (2024-08-29 16:21:09)

fix: missing status update in KMP controller
# Description

## What this PR does / why we need it:

In this PR the `writeKMProviderStatus` and helper functions were moved from the `refresher` back to the controller to ensure status messages get written to the KMP resource. 

## Which issue(s) this PR fixes *(optional, using `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when the PR gets merged)*:
Fixes #

#1733 

## Type of change

Please delete options that are not relevant.

- [x] Bug fix (non-breaking change which fixes an issue)

# How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Please also list any relevant details for your test configuration

- [ ] Test A
- [ ] Test B

# Checklist:

- [x] Does the affected code have corresponding tests?
- [x] Do all new files have appropriate license header?

# Post Merge Requirements
- [ ] MAINTAINERS: manually trigger the "Publish Package" workflow after merging any PR that indicates `Helm Chart Change`


binbin-li: @duffney PR lgtm, could you update commits to be verified so that we can merge it?

Patch:
diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml
index c2a31ba..804ea6a 100644
--- a/.github/workflows/build-pr.yml
+++ b/.github/workflows/build-pr.yml
@@ -15,7 +15,7 @@ jobs:
     uses: ./.github/workflows/e2e-cli.yml
     secrets:
       CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
-   
+
   call_test_e2e_basic:
     name: "run e2e on basic matrix"
     if: ${{ ! (contains(github.event.pull_request.labels.*.name, 'safe to test') || github.event_name == 'workflow_dispatch') }}
@@ -26,7 +26,7 @@ jobs:
       matrix:
         KUBERNETES_VERSION: ["1.29.2"]
         GATEKEEPER_VERSION: ["3.17.0"]
-    uses: ./.github/workflows/e2e-k8s.yml 
+    uses: ./.github/workflows/e2e-k8s.yml
     with:
       k8s_version: ${{ matrix.KUBERNETES_VERSION }}
       gatekeeper_version: ${{ matrix.GATEKEEPER_VERSION }}
@@ -39,10 +39,10 @@ jobs:
       matrix:
         KUBERNETES_VERSION: ["1.28.12", "1.29.2"]
         GATEKEEPER_VERSION: ["3.15.0", "3.16.0", "3.17.0"]
-    uses: ./.github/workflows/e2e-k8s.yml 
+    uses: ./.github/workflows/e2e-k8s.yml
     with:
       k8s_version: ${{ matrix.KUBERNETES_VERSION }}
-      gatekeeper_version: ${{ matrix.GATEKEEPER_VERSION }} 
+      gatekeeper_version: ${{ matrix.GATEKEEPER_VERSION }}
 
   build_test_aks_e2e_conditional:
     name: "Build and run e2e Test on AKS with conditions"
@@ -60,9 +60,9 @@ jobs:
       k8s_version: ${{ matrix.KUBERNETES_VERSION }}
       gatekeeper_version: ${{ matrix.GATEKEEPER_VERSION }}
     secrets: inherit
-  
+
   aks-test-cleanup:
-    needs: ['build_test_aks_e2e_conditional']
+    needs: ["build_test_aks_e2e_conditional"]
     runs-on: ubuntu-latest
     permissions:
       id-token: write
@@ -79,7 +79,7 @@ jobs:
       - name: Set up Go 1.22
         uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
         with:
-          go-version: '1.22'
+          go-version: "1.22"
 
       - name: Az CLI login
         uses: azure/login@6c251865b4e6290e7b78be643ea2d005bc51f69a # v2.1.1
@@ -90,4 +90,4 @@ jobs:
 
       - name: clean up
         run: |
-          make e2e-cleanup AZURE_SUBSCRIPTION_ID=${{ secrets.AZURE_SUBSCRIPTION_ID }}
\ No newline at end of file
+          make e2e-cleanup AZURE_SUBSCRIPTION_ID=${{ secrets.AZURE_SUBSCRIPTION_ID }}
diff --git a/.github/workflows/cache-cleanup.yml b/.github/workflows/cache-cleanup.yml
index a248774..46042f7 100644
--- a/.github/workflows/cache-cleanup.yml
+++ b/.github/workflows/cache-cleanup.yml
@@ -10,7 +10,7 @@ permissions:
 jobs:
   cleanup:
     runs-on: ubuntu-latest
-    steps:      
+    steps:
       - name: Harden Runner
         uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
@@ -19,7 +19,7 @@ jobs:
       - name: Cleanup
         run: |
           gh extension install actions/gh-actions-cache
-          
+
           echo "Fetching list of cache key"
           cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 )
 
@@ -34,4 +34,4 @@ jobs:
         env:
           GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           REPO: ${{ github.repository }}
-          BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
\ No newline at end of file
+          BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
diff --git a/.github/workflows/clean-dev-package.yml b/.github/workflows/clean-dev-package.yml
index e355094..0a53bd8 100644
--- a/.github/workflows/clean-dev-package.yml
+++ b/.github/workflows/clean-dev-package.yml
@@ -10,7 +10,7 @@ jobs:
   cleanup-packages:
     runs-on: ubuntu-latest
     permissions:
-        packages: write
+      packages: write
     steps:
       - name: Harden Runner
         uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
@@ -19,15 +19,15 @@ jobs:
 
       - name: Clean up ratify-crds-dev
         uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0
-        with: 
-          package-name: 'ratify-crds-dev'
-          package-type: 'container'
+        with:
+          package-name: "ratify-crds-dev"
+          package-type: "container"
           min-versions-to-keep: 7
           delete-only-pre-release-versions: "true"
       - name: Clean up ratify-dev
         uses: actions/delete-package-versions@e5bc658cc4c965c472efe991f8beea3981499c55 # v5.0.0
-        with: 
-          package-name: 'ratify-dev'
-          package-type: 'container'
+        with:
+          package-name: "ratify-dev"
+          package-type: "container"
           min-versions-to-keep: 7
-          delete-only-pre-release-versions: "true"
\ No newline at end of file
+          delete-only-pre-release-versions: "true"
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 4d15ab2..fe0ac83 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -1,19 +1,18 @@
-
 name: "CodeQL Scan"
 
 on:
   push:
-    branches: 
+    branches:
       - main
       - dev
       - 1.0.0*
   pull_request:
-    branches: 
+    branches:
       - main
       - dev
       - 1.0.0*
   schedule:
-    - cron: '30 1 * * 0'
+    - cron: "30 1 * * 0"
   workflow_dispatch:
 
 permissions: read-all
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index 769e060..cb827af 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -21,7 +21,7 @@ jobs:
 
       - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
         with:
-          go-version: '1.22'
+          go-version: "1.22"
       - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
       - name: golangci-lint
         uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0
diff --git a/.github/workflows/high-availability.yml b/.github/workflows/high-availability.yml
index af3ec3b..631f9bb 100644
--- a/.github/workflows/high-availability.yml
+++ b/.github/workflows/high-availability.yml
@@ -39,7 +39,7 @@ jobs:
       - name: Set up Go 1.22
         uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
         with:
-          go-version: '1.22'
+          go-version: "1.22"
 
       - name: Bootstrap e2e
         run: |
diff --git a/.github/workflows/pr-to-main.yml b/.github/workflows/pr-to-main.yml
index 909d7b2..5fcefe2 100644
--- a/.github/workflows/pr-to-main.yml
+++ b/.github/workflows/pr-to-main.yml
@@ -2,7 +2,7 @@ name: pr_to_main
 
 on:
   schedule:
-    - cron: '30 8 * * 0'  # early morning (08:30 UTC) every Sunday
+    - cron: "30 8 * * 0" # early morning (08:30 UTC) every Sunday
   workflow_dispatch:
 
 permissions:
diff --git a/.github/workflows/publish-charts.yml b/.github/workflows/publish-charts.yml
index 44b774b..8508387 100644
--- a/.github/workflows/publish-charts.yml
+++ b/.github/workflows/publish-charts.yml
@@ -21,4 +21,4 @@ jobs:
       - name: Publish Helm charts
         uses: stefanprodan/helm-gh-pages@0ad2bb377311d61ac04ad9eb6f252fb68e207260 # v1.7.0
         with:
-          token: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+          token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/publish-cosign-sample.yml b/.github/workflows/publish-cosign-sample.yml
index 2dd2042..566c278 100644
--- a/.github/workflows/publish-cosign-sample.yml
+++ b/.github/workflows/publish-cosign-sample.yml
@@ -1,11 +1,11 @@
 name: publish-cosign-sample
 
-on: 
+on:
   workflow_dispatch:
-   
+
 env:
   REGISTRY: ghcr.io
-  
+
 permissions:
   contents: read
 
@@ -18,7 +18,7 @@ jobs:
       contents: write
       packages: write
       id-token: write
-    steps:            
+    steps:
       - name: Harden Runner
         uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
@@ -28,7 +28,7 @@ jobs:
         uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0
 
       - name: Get repo
-        run: |          
+        run: |
           echo "REPOSITORY=${{ env.REGISTRY }}/${{ github.repository }}" >> $GITHUB_ENV
 
       - name: Write signing key to disk
diff --git a/.github/workflows/publish-dev-assets.yml b/.github/workflows/publish-dev-assets.yml
index 0bc23c8..c64a243 100644
--- a/.github/workflows/publish-dev-assets.yml
+++ b/.github/workflows/publish-dev-assets.yml
@@ -2,7 +2,7 @@ name: publish-dev-assets
 
 on:
   schedule:
-    - cron: '30 8 * * 0'  # early morning (08:30 UTC) every Sunday
+    - cron: "30 8 * * 0" # early morning (08:30 UTC) every Sunday
   workflow_dispatch:
 
 permissions: read-all
@@ -108,11 +108,11 @@ jobs:
         run: |
           sed -i '/^  repository:/c\  repository: ghcr.io/ratify-project/ratify-dev' charts/ratify/values.yaml
           sed -i '/^  crdRepository:/c\  crdRepository: ghcr.io/ratify-project/ratify-crds-dev' charts/ratify/values.yaml
-          sed -i '/^  tag:/c\  tag: ${{ steps.prepare.outputs.version }}' charts/ratify/values.yaml 
+          sed -i '/^  tag:/c\  tag: ${{ steps.prepare.outputs.version }}' charts/ratify/values.yaml
       - name: helm package
         run: |
-            helm package ./charts/ratify --version ${{ steps.prepare.outputs.semversion }}
-            helm package ./charts/ratify --version ${{ steps.prepare.outputs.semversionrolling }}
+          helm package ./charts/ratify --version ${{ steps.prepare.outputs.semversion }}
+          helm package ./charts/ratify --version ${{ steps.prepare.outputs.semversionrolling }}
       - name: helm push
         run: |
           helm push ratify-${{ steps.prepare.outputs.semversion }}.tgz oci://${{ steps.prepare.outputs.chartrepo }}
diff --git a/.github/workflows/publish-sample.yml b/.github/workflows/publish-sample.yml
index 91cd14a..5298179 100644
--- a/.github/workflows/publish-sample.yml
+++ b/.github/workflows/publish-sample.yml
@@ -1,11 +1,11 @@
 name: publish-sample
 
-on: 
- workflow_dispatch:
+on:
+  workflow_dispatch:
 
 env:
   REGISTRY: ghcr.io
-  
+
 permissions:
   contents: read
 
@@ -17,14 +17,14 @@ jobs:
     permissions:
       contents: write
       packages: write
-    steps:            
+    steps:
       - name: Harden Runner
         uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
           egress-policy: audit
 
       - name: Get repo
-        run: |          
+        run: |
           echo "REPOSITORY=${{ env.REGISTRY }}/${{ github.repository }}" >> $GITHUB_ENV
 
       - name: Log in to the GHCR
@@ -35,9 +35,7 @@ jobs:
           password: ${{ secrets.GITHUB_TOKEN }}
 
       - name: Copy signed sample test image
-        run: 
-          oras cp -r wabbitnetworks.azurecr.io/ratify/notary-image:signed ${REPOSITORY}/notary-image:signed
+        run: oras cp -r wabbitnetworks.azurecr.io/ratify/notary-image:signed ${REPOSITORY}/notary-image:signed
 
-      - name: Copy unsigned sample test image 
-        run: 
-          oras cp wabbitnetworks.azurecr.io/ratify/notary-image:unsigned ${REPOSITORY}/notary-image:unsigned
+      - name: Copy unsigned sample test image
+        run: oras cp wabbitnetworks.azurecr.io/ratify/notary-image:unsigned ${REPOSITORY}/notary-image:unsigned
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index ab898be..e261c1b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -3,7 +3,7 @@ name: Release Ratify
 on:
   push:
     tags:
-      - 'v*'
+      - "v*"
   workflow_dispatch:
 
 permissions: read-all
@@ -15,41 +15,41 @@ jobs:
     permissions:
       contents: write
     steps:
-    - name: Harden Runner
-      uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
-      with:
-        egress-policy: audit
-
-    - name: Checkout
-      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # tag=3.0.2
-      with:
+      - name: Harden Runner
+        uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
+        with:
+          egress-policy: audit
+
+      - name: Checkout
+        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # tag=3.0.2
+        with:
           fetch-depth: 0
-    
-    - name: Install Syft
-      uses: anchore/sbom-action/download-syft@61119d458adab75f756bc0b9e4bde25725f86a7a # v0.17.2
-          
-    - name: Set up Go
-      uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
-      with:
-        go-version: '1.22'
-
-    - name: Goreleaser
-      id: goreleaser
-      uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0
-      with:
-        version: '2.0.1'
-        args: release --clean
-      env:
+
+      - name: Install Syft
+        uses: anchore/sbom-action/download-syft@61119d458adab75f756bc0b9e4bde25725f86a7a # v0.17.2
+
+      - name: Set up Go
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
+        with:
+          go-version: "1.22"
+
+      - name: Goreleaser
+        id: goreleaser
+        uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0
+        with:
+          version: "2.0.1"
+          args: release --clean
+        env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
-    - name: Generate SBOM
-      run: |
-        curl -Lo $RUNNER_TEMP/sbom-tool https://github.com/microsoft/sbom-tool/releases/latest/download/sbom-tool-linux-x64
-        chmod +x $RUNNER_TEMP/sbom-tool
-        $RUNNER_TEMP/sbom-tool generate -b . -bc . -pn ratify -pv $GITHUB_REF_NAME -ps Microsoft -nsb https://microsoft.com -V Verbose
-
-    - name: Upload a Build Artifact
-      uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # tag=v4.4.0
-      with:
-        name: SBOM SPDX files
-        path: _manifest/spdx_2.2/**
+      - name: Generate SBOM
+        run: |
+          curl -Lo $RUNNER_TEMP/sbom-tool https://github.com/microsoft/sbom-tool/releases/latest/download/sbom-tool-linux-x64
+          chmod +x $RUNNER_TEMP/sbom-tool
+          $RUNNER_TEMP/sbom-tool generate -b . -bc . -pn ratify -pv $GITHUB_REF_NAME -ps Microsoft -nsb https://microsoft.com -V Verbose
+
+      - name: Upload a Build Artifact
+        uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # tag=v4.4.0
+        with:
+          name: SBOM SPDX files
+          path: _manifest/spdx_2.2/**
diff --git a/.github/workflows/run-full-validation.yml b/.github/workflows/run-full-validation.yml
index f6d03c1..3f2464c 100644
--- a/.github/workflows/run-full-validation.yml
+++ b/.github/workflows/run-full-validation.yml
@@ -28,7 +28,7 @@ jobs:
       matrix:
         KUBERNETES_VERSION: ["1.28.12", "1.29.2"]
         GATEKEEPER_VERSION: ["3.15.0", "3.16.0", "3.17.0"]
-    uses: ./.github/workflows/e2e-k8s.yml 
+    uses: ./.github/workflows/e2e-k8s.yml
     with:
       k8s_version: ${{ matrix.KUBERNETES_VERSION }}
       gatekeeper_version: ${{ matrix.GATEKEEPER_VERSION }}
@@ -50,7 +50,7 @@ jobs:
     secrets: inherit
 
   aks-test-cleanup:
-    needs: ['build_test_aks_e2e']
+    needs: ["build_test_aks_e2e"]
     runs-on: ubuntu-latest
     permissions:
       id-token: write
@@ -67,7 +67,7 @@ jobs:
       - name: Set up Go 1.22
         uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
         with:
-          go-version: '1.22'
+          go-version: "1.22"
 
       - name: Az CLI login
         uses: azure/login@6c251865b4e6290e7b78be643ea2d005bc51f69a # v2.1.1
@@ -78,4 +78,4 @@ jobs:
 
       - name: clean up
         run: |
-          make e2e-cleanup AZURE_SUBSCRIPTION_ID=${{ secrets.AZURE_SUBSCRIPTION_ID }}
\ No newline at end of file
+          make e2e-cleanup AZURE_SUBSCRIPTION_ID=${{ secrets.AZURE_SUBSCRIPTION_ID }}
diff --git a/.github/workflows/scan-vulns.yaml b/.github/workflows/scan-vulns.yaml
index 105eed1..aed9bba 100644
--- a/.github/workflows/scan-vulns.yaml
+++ b/.github/workflows/scan-vulns.yaml
@@ -11,7 +11,7 @@ on:
       - "library/**"
       - "**.md"
   schedule:
-    - cron: '30 8 * * 0'  # early morning (08:30 UTC) every Sunday
+    - cron: "30 8 * * 0" # early morning (08:30 UTC) every Sunday
   workflow_dispatch:
 
 permissions: read-all
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index 2180ee3..96efefe 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -3,7 +3,7 @@ on:
   branch_protection_rule:
   schedule:
     # Weekly on Saturdays.
-    - cron: '30 1 * * 6'
+    - cron: "30 1 * * 6"
   push:
     branches:
       - main
@@ -27,7 +27,7 @@ jobs:
       id-token: write
       actions: read
       contents: read
-    
+
     steps:
       - name: Harden Runner
         uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
@@ -53,7 +53,7 @@ jobs:
           name: SARIF file
           path: results.sarif
           retention-days: 5
-      
+
       - name: "Upload to code-scanning"
         uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # tag=v3.26.6
         with:
diff --git a/.github/workflows/sync-gh-pages.yml b/.github/workflows/sync-gh-pages.yml
index 9af8087..8c584c7 100644
--- a/.github/workflows/sync-gh-pages.yml
+++ b/.github/workflows/sync-gh-pages.yml
@@ -2,9 +2,9 @@ name: Sync GH Pages
 on:
   push:
     branches:
-    - main
+      - main
     paths:
-    - library/**
+      - library/**
 
 permissions: read-all
 
@@ -26,5 +26,5 @@ jobs:
         with:
           github_token: ${{ github.token }}
           source_ref: ${{ github.ref }}
-          target_branch: 'gh-pages'
-          commit_message_template: '[Automated] Merged {source_ref} into target {target_branch}'
\ No newline at end of file
+          target_branch: "gh-pages"
+          commit_message_template: "[Automated] Merged {source_ref} into target {target_branch}"
diff --git a/pkg/controllers/clusterresource/keymanagementprovider_controller.go b/pkg/controllers/clusterresource/keymanagementprovider_controller.go
index 93dda98..afb53a9 100644
--- a/pkg/controllers/clusterresource/keymanagementprovider_controller.go
+++ b/pkg/controllers/clusterresource/keymanagementprovider_controller.go
@@ -18,11 +18,19 @@ package clusterresource
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 
+	re "github.com/ratify-project/ratify/errors"
+	"github.com/ratify-project/ratify/internal/constants"
+	cutils "github.com/ratify-project/ratify/pkg/controllers/utils"
+	kmp "github.com/ratify-project/ratify/pkg/keymanagementprovider"
 	_ "github.com/ratify-project/ratify/pkg/keymanagementprovider/azurekeyvault" // register azure key vault key management provider
 	_ "github.com/ratify-project/ratify/pkg/keymanagementprovider/inline"        // register inline key management provider
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider/refresh"
+	"github.com/sirupsen/logrus"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -37,20 +45,91 @@ type KeyManagementProviderReconciler struct {
 	Scheme *runtime.Scheme
 }
 
-func (r *KeyManagementProviderReconciler) ReconcileWithConfig(ctx context.Context, config map[string]interface{}) (ctrl.Result, error) {
-	refresher, err := refresh.CreateRefresherFromConfig(config)
-	if err != nil {
+func (r *KeyManagementProviderReconciler) ReconcileWithType(ctx context.Context, req ctrl.Request, refresherType string) (ctrl.Result, error) {
+	logger := logrus.WithContext(ctx)
+
+	var keyManagementProvider configv1beta1.KeyManagementProvider
+
+	resource := req.Name
+
+	logger.Infof("reconciling cluster key management provider '%v'", resource)
+
+	if err := r.Get(ctx, req.NamespacedName, &keyManagementProvider); err != nil {
+		if apierrors.IsNotFound(err) {
+			logger.Infof("deletion detected, removing key management provider %v", resource)
+			kmp.DeleteResourceFromMap(resource)
+		} else {
+			logger.Error(err, "unable to fetch key management provider")
+		}
+
+		return ctrl.Result{}, client.IgnoreNotFound(err)
+	}
+
+	lastFetchedTime := metav1.Now()
+
+	// get certificate store list to check if certificate store is configured
+	// TODO: remove check in v2.0.0+
+	var certificateStoreList configv1beta1.CertificateStoreList
+	if err := r.List(ctx, &certificateStoreList); err != nil {
+		logger.Error(err, "unable to list certificate stores")
 		return ctrl.Result{}, err
 	}
+
+	if len(certificateStoreList.Items) > 0 {
+		// Note: for backwards compatibility in upgrade scenarios, Ratify will only log a warning statement.
+		logger.Warn("Certificate Store already exists. Key management provider and certificate store should not be configured together. Please migrate to key management provider and delete certificate store.")
+	}
+
+	provider, err := cutils.SpecToKeyManagementProvider(keyManagementProvider.Spec.Parameters.Raw, keyManagementProvider.Spec.Type)
+	if err != nil {
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to create key management provider from CR")
+
+		kmp.SetCertificateError(resource, kmpErr)
+		kmp.SetKeyError(resource, kmpErr)
+		writeKMProviderStatus(ctx, r, &keyManagementProvider, logger, false, &kmpErr, lastFetchedTime, nil)
+		return ctrl.Result{}, kmpErr
+	}
+
+	refresherConfig := refresh.RefresherConfig{
+		RefresherType:           refresherType,
+		Provider:                provider,
+		ProviderType:            keyManagementProvider.Spec.Type,
+		ProviderRefreshInterval: keyManagementProvider.Spec.RefreshInterval,
+		Resource:                resource,
+	}
+
+	refresher, err := refresh.CreateRefresherFromConfig(refresherConfig)
+	if err != nil {
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to create refresher from config")
+		kmp.SetCertificateError(resource, kmpErr)
+		kmp.SetKeyError(resource, kmpErr)
+		writeKMProviderStatus(ctx, r, &keyManagementProvider, logger, false, &kmpErr, lastFetchedTime, nil)
+		return ctrl.Result{}, kmpErr
+	}
+
 	err = refresher.Refresh(ctx)
 	if err != nil {
-		return ctrl.Result{}, err
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to refresh key management provider")
+		writeKMProviderStatus(ctx, r, &keyManagementProvider, logger, false, &kmpErr, lastFetchedTime, nil)
+		return ctrl.Result{}, kmpErr
 	}
 
 	result, ok := refresher.GetResult().(ctrl.Result)
 	if !ok {
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to get result from refresher")
+		writeKMProviderStatus(ctx, r, &keyManagementProvider, logger, false, &kmpErr, lastFetchedTime, nil)
 		return ctrl.Result{}, fmt.Errorf("unexpected type returned from GetResult: %T", refresher.GetResult())
 	}
+
+	status, ok := refresher.GetStatus().(kmp.KeyManagementProviderStatus)
+	if !ok {
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to get status from refresher")
+		writeKMProviderStatus(ctx, r, &keyManagementProvider, logger, false, &kmpErr, lastFetchedTime, nil)
+		return ctrl.Result{}, fmt.Errorf("unexpected type returned from GetStatus: %T", refresher.GetStatus())
+	}
+
+	writeKMProviderStatus(ctx, r, &keyManagementProvider, logger, true, nil, lastFetchedTime, status)
+
 	return result, nil
 }
 
@@ -58,12 +137,7 @@ func (r *KeyManagementProviderReconciler) ReconcileWithConfig(ctx context.Contex
 // +kubebuilder:rbac:groups=config.ratify.deislabs.io,resources=keymanagementproviders/status,verbs=get;update;patch
 // +kubebuilder:rbac:groups=config.ratify.deislabs.io,resources=keymanagementproviders/finalizers,verbs=update
 func (r *KeyManagementProviderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
-	refresherConfig := map[string]interface{}{
-		"type":    refresh.KubeRefresherType,
-		"client":  r.Client,
-		"request": req,
-	}
-	return r.ReconcileWithConfig(ctx, refresherConfig)
+	return r.ReconcileWithType(ctx, req, refresh.KubeRefresherType)
 }
 
 // SetupWithManager sets up the controller with the Manager.
@@ -77,3 +151,40 @@ func (r *KeyManagementProviderReconciler) SetupWithManager(mgr ctrl.Manager) err
 		For(&configv1beta1.KeyManagementProvider{}).WithEventFilter(pred).
 		Complete(r)
 }
+
+func writeKMProviderStatus(ctx context.Context, r client.StatusClient, keyManagementProvider *configv1beta1.KeyManagementProvider, logger *logrus.Entry, isSuccess bool, err *re.Error, operationTime metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
+	if isSuccess {
+		updateKMProviderSuccessStatus(keyManagementProvider, &operationTime, kmProviderStatus)
+	} else {
+		updateKMProviderErrorStatus(keyManagementProvider, err, &operationTime)
+	}
+	if statusErr := r.Status().Update(ctx, keyManagementProvider); statusErr != nil {
+		logger.Error(statusErr, ",unable to update key management provider error status")
+	}
+}
+
+// updateKMProviderErrorStatus updates the key management provider status with error, brief error and last fetched time
+func updateKMProviderErrorStatus(keyManagementProvider *configv1beta1.KeyManagementProvider, err *re.Error, operationTime *metav1.Time) {
+	keyManagementProvider.Status.IsSuccess = false
+	keyManagementProvider.Status.Error = err.Error()
+	keyManagementProvider.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
+	keyManagementProvider.Status.LastFetchedTime = operationTime
+}
+
+// updateKMProviderSuccessStatus updates the key management provider status if status argument is non nil
+// Success status includes last fetched time and other provider-specific properties
+func updateKMProviderSuccessStatus(keyManagementProvider *configv1beta1.KeyManagementProvider, lastOperationTime *metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
+	keyManagementProvider.Status.IsSuccess = true
+	keyManagementProvider.Status.Error = ""
+	keyManagementProvider.Status.BriefError = ""
+	keyManagementProvider.Status.LastFetchedTime = lastOperationTime
+
+	if kmProviderStatus != nil {
+		jsonString, _ := json.Marshal(kmProviderStatus)
+
+		raw := runtime.RawExtension{
+			Raw: jsonString,
+		}
+		keyManagementProvider.Status.Properties = raw
+	}
+}
diff --git a/pkg/controllers/namespaceresource/keymanagementprovider_controller.go b/pkg/controllers/namespaceresource/keymanagementprovider_controller.go
index ba439a2..2bbdd0b 100644
--- a/pkg/controllers/namespaceresource/keymanagementprovider_controller.go
+++ b/pkg/controllers/namespaceresource/keymanagementprovider_controller.go
@@ -18,11 +18,18 @@ package namespaceresource
 
 import (
 	"context"
-	"fmt"
+	"encoding/json"
 
+	re "github.com/ratify-project/ratify/errors"
+	"github.com/ratify-project/ratify/internal/constants"
+	cutils "github.com/ratify-project/ratify/pkg/controllers/utils"
+	kmp "github.com/ratify-project/ratify/pkg/keymanagementprovider"
 	_ "github.com/ratify-project/ratify/pkg/keymanagementprovider/azurekeyvault" // register azure key vault key management provider
 	_ "github.com/ratify-project/ratify/pkg/keymanagementprovider/inline"        // register inline key management provider
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider/refresh"
+	"github.com/sirupsen/logrus"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -37,20 +44,89 @@ type KeyManagementProviderReconciler struct {
 	Scheme *runtime.Scheme
 }
 
-func (r *KeyManagementProviderReconciler) ReconcileWithConfig(ctx context.Context, config map[string]interface{}) (ctrl.Result, error) {
-	refresher, err := refresh.CreateRefresherFromConfig(config)
-	if err != nil {
+func (r *KeyManagementProviderReconciler) ReconcileWithType(ctx context.Context, req ctrl.Request, refresherType string) (ctrl.Result, error) {
+	logger := logrus.WithContext(ctx)
+
+	var resource = req.NamespacedName.String()
+	var keyManagementProvider configv1beta1.NamespacedKeyManagementProvider
+
+	logger.Infof("reconciling cluster key management provider '%v'", resource)
+
+	if err := r.Get(ctx, req.NamespacedName, &keyManagementProvider); err != nil {
+		if apierrors.IsNotFound(err) {
+			logger.Infof("deletion detected, removing key management provider %v", resource)
+			kmp.DeleteResourceFromMap(resource)
+		} else {
+			logger.Error(err, "unable to fetch key management provider")
+		}
+
+		return ctrl.Result{}, client.IgnoreNotFound(err)
+	}
+
+	lastFetchedTime := metav1.Now()
+	isFetchSuccessful := false
+
+	// get certificate store list to check if certificate store is configured
+	// TODO: remove check in v2.0.0+
+	var certificateStoreList configv1beta1.CertificateStoreList
+	if err := r.List(ctx, &certificateStoreList); err != nil {
+		logger.Error(err, "unable to list certificate stores")
 		return ctrl.Result{}, err
 	}
+
+	if len(certificateStoreList.Items) > 0 {
+		// Note: for backwards compatibility in upgrade scenarios, Ratify will only log a warning statement.
+		logger.Warn("Certificate Store already exists. Key management provider and certificate store should not be configured together. Please migrate to key management provider and delete certificate store.")
+	}
+
+	provider, err := cutils.SpecToKeyManagementProvider(keyManagementProvider.Spec.Parameters.Raw, keyManagementProvider.Spec.Type)
+	if err != nil {
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to create key management provider from CR")
+
+		kmp.SetCertificateError(resource, err)
+		kmp.SetKeyError(resource, err)
+		writeKMProviderStatusNamespaced(ctx, r, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
+		return ctrl.Result{}, kmpErr
+	}
+
+	refresherConfig := refresh.RefresherConfig{
+		RefresherType:           refresherType,
+		Provider:                provider,
+		ProviderType:            keyManagementProvider.Spec.Type,
+		ProviderRefreshInterval: keyManagementProvider.Spec.RefreshInterval,
+		Resource:                resource,
+	}
+
+	refresher, err := refresh.CreateRefresherFromConfig(refresherConfig)
+	if err != nil {
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to create refresher from config")
+		writeKMProviderStatusNamespaced(ctx, r, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
+		return ctrl.Result{}, kmpErr
+	}
+
 	err = refresher.Refresh(ctx)
 	if err != nil {
-		return ctrl.Result{}, err
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to refresh key management provider")
+		writeKMProviderStatusNamespaced(ctx, r, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
+		return ctrl.Result{}, kmpErr
 	}
 
 	result, ok := refresher.GetResult().(ctrl.Result)
 	if !ok {
-		return ctrl.Result{}, fmt.Errorf("unexpected type returned from GetResult: %T", refresher.GetResult())
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to get result from refresher")
+		writeKMProviderStatusNamespaced(ctx, r, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
+		return ctrl.Result{}, kmpErr
+	}
+
+	status, ok := refresher.GetStatus().(kmp.KeyManagementProviderStatus)
+	if !ok {
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail("Failed to get status from refresher")
+		writeKMProviderStatusNamespaced(ctx, r, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
+		return ctrl.Result{}, &kmpErr
 	}
+
+	writeKMProviderStatusNamespaced(ctx, r, &keyManagementProvider, logger, true, nil, lastFetchedTime, status)
+
 	return result, nil
 }
 
@@ -58,12 +134,7 @@ func (r *KeyManagementProviderReconciler) ReconcileWithConfig(ctx context.Contex
 // +kubebuilder:rbac:groups=config.ratify.deislabs.io,resources=namespacedkeymanagementproviders/status,verbs=get;update;patch
 // +kubebuilder:rbac:groups=config.ratify.deislabs.io,resources=namespacedkeymanagementproviders/finalizers,verbs=update
 func (r *KeyManagementProviderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
-	refresherConfig := map[string]interface{}{
-		"type":    refresh.KubeRefresherNamespacedType,
-		"client":  r.Client,
-		"request": req,
-	}
-	return r.ReconcileWithConfig(ctx, refresherConfig)
+	return r.ReconcileWithType(ctx, req, refresh.KubeRefresherType)
 }
 
 // SetupWithManager sets up the controller with the Manager.
@@ -77,3 +148,40 @@ func (r *KeyManagementProviderReconciler) SetupWithManager(mgr ctrl.Manager) err
 		For(&configv1beta1.NamespacedKeyManagementProvider{}).WithEventFilter(pred).
 		Complete(r)
 }
+
+// writeKMProviderStatusNamespaced updates the status of the key management provider resource
+func writeKMProviderStatusNamespaced(ctx context.Context, r client.StatusClient, keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, logger *logrus.Entry, isSuccess bool, err *re.Error, operationTime metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
+	if isSuccess {
+		updateKMProviderSuccessStatusNamespaced(keyManagementProvider, &operationTime, kmProviderStatus)
+	} else {
+		updateKMProviderErrorStatusNamespaced(keyManagementProvider, err, &operationTime)
+	}
+	if statusErr := r.Status().Update(ctx, keyManagementProvider); statusErr != nil {
+		logger.Error(statusErr, ",unable to update key management provider error status")
+	}
+}
+
+// updateKMProviderErrorStatusNamespaced updates the key management provider status with error, brief error and last fetched time
+func updateKMProviderErrorStatusNamespaced(keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, err *re.Error, operationTime *metav1.Time) {
+	keyManagementProvider.Status.IsSuccess = false
+	keyManagementProvider.Status.Error = err.Error()
+	keyManagementProvider.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
+	keyManagementProvider.Status.LastFetchedTime = operationTime
+}
+
+// Success status includes last fetched time and other provider-specific properties
+func updateKMProviderSuccessStatusNamespaced(keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, lastOperationTime *metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
+	keyManagementProvider.Status.IsSuccess = true
+	keyManagementProvider.Status.Error = ""
+	keyManagementProvider.Status.BriefError = ""
+	keyManagementProvider.Status.LastFetchedTime = lastOperationTime
+
+	if kmProviderStatus != nil {
+		jsonString, _ := json.Marshal(kmProviderStatus)
+
+		raw := runtime.RawExtension{
+			Raw: jsonString,
+		}
+		keyManagementProvider.Status.Properties = raw
+	}
+}
diff --git a/pkg/keymanagementprovider/mocks/client.go b/pkg/keymanagementprovider/mocks/client.go
index f24c190..4d651ce 100644
--- a/pkg/keymanagementprovider/mocks/client.go
+++ b/pkg/keymanagementprovider/mocks/client.go
@@ -17,7 +17,7 @@ package mocks
 
 import (
 	"context"
-	"fmt"
+	"errors"
 
 	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -25,8 +25,43 @@ import (
 
 type TestClient struct {
 	client.Client
+	GetFunc  func(ctx context.Context, key types.NamespacedName, obj client.Object) error
+	ListFunc func(ctx context.Context, list client.ObjectList) error
 }
 
-func (m TestClient) Get(_ context.Context, _ types.NamespacedName, _ client.Object, _ ...client.GetOption) error {
-	return fmt.Errorf("error")
+func (m TestClient) Get(_ context.Context, key types.NamespacedName, obj client.Object, _ ...client.GetOption) error {
+	if m.GetFunc != nil {
+		return m.GetFunc(context.Background(), key, obj)
+	}
+	return nil
+}
+
+func (m TestClient) List(_ context.Context, list client.ObjectList, _ ...client.ListOption) error {
+	if m.ListFunc != nil {
+		return m.ListFunc(context.Background(), list)
+	}
+	return nil
+}
+
+type mockSubResourceWriter struct {
+	updateFailed bool
+}
+
+func (m *TestClient) Status() client.StatusWriter {
+	return &mockSubResourceWriter{updateFailed: false}
+}
+
+func (m *mockSubResourceWriter) Create(_ context.Context, _ client.Object, _ client.Object, _ ...client.SubResourceCreateOption) error {
+	return nil
+}
+
+func (m *mockSubResourceWriter) Patch(_ context.Context, _ client.Object, _ client.Patch, _ ...client.SubResourcePatchOption) error {
+	return nil
+}
+
+func (m *mockSubResourceWriter) Update(_ context.Context, _ client.Object, _ ...client.SubResourceUpdateOption) error {
+	if m.updateFailed {
+		return errors.New("update failed")
+	}
+	return nil
 }
diff --git a/pkg/keymanagementprovider/mocks/factory.go b/pkg/keymanagementprovider/mocks/factory.go
index 0230582..15a0e0d 100644
--- a/pkg/keymanagementprovider/mocks/factory.go
+++ b/pkg/keymanagementprovider/mocks/factory.go
@@ -16,6 +16,7 @@ limitations under the License.
 package mocks
 
 import (
+	"context"
 	"crypto"
 	"crypto/x509"
 
@@ -24,10 +25,19 @@ import (
 )
 
 type TestKeyManagementProviderFactory struct {
+	GetCertsFunc      func(ctx context.Context) (map[keymanagementprovider.KMPMapKey][]*x509.Certificate, keymanagementprovider.KeyManagementProviderStatus, error)
+	GetKeysFunc       func(ctx context.Context) (map[keymanagementprovider.KMPMapKey]crypto.PublicKey, keymanagementprovider.KeyManagementProviderStatus, error)
+	IsRefreshableFunc func() bool
 }
 
 func (f *TestKeyManagementProviderFactory) Create(_ string, _ config.KeyManagementProviderConfig, _ string) (keymanagementprovider.KeyManagementProvider, error) {
 	var certMap map[keymanagementprovider.KMPMapKey][]*x509.Certificate
 	var keyMap map[keymanagementprovider.KMPMapKey]crypto.PublicKey
-	return &TestKeyManagementProvider{certificates: certMap, keys: keyMap}, nil
+	return &TestKeyManagementProvider{
+		certificates:        certMap,
+		keys:                keyMap,
+		GetCertificatesFunc: f.GetCertsFunc,
+		GetKeysFunc:         f.GetKeysFunc,
+		IsRefreshableFunc:   f.IsRefreshableFunc,
+	}, nil
 }
diff --git a/pkg/keymanagementprovider/mocks/types.go b/pkg/keymanagementprovider/mocks/types.go
index 246de21..5cfa216 100644
--- a/pkg/keymanagementprovider/mocks/types.go
+++ b/pkg/keymanagementprovider/mocks/types.go
@@ -24,20 +24,32 @@ import (
 )
 
 type TestKeyManagementProvider struct {
-	certificates map[keymanagementprovider.KMPMapKey][]*x509.Certificate
-	keys         map[keymanagementprovider.KMPMapKey]crypto.PublicKey
-	status       keymanagementprovider.KeyManagementProviderStatus
-	err          error
+	certificates        map[keymanagementprovider.KMPMapKey][]*x509.Certificate
+	keys                map[keymanagementprovider.KMPMapKey]crypto.PublicKey
+	status              keymanagementprovider.KeyManagementProviderStatus
+	err                 error
+	GetCertificatesFunc func(ctx context.Context) (map[keymanagementprovider.KMPMapKey][]*x509.Certificate, keymanagementprovider.KeyManagementProviderStatus, error)
+	GetKeysFunc         func(ctx context.Context) (map[keymanagementprovider.KMPMapKey]crypto.PublicKey, keymanagementprovider.KeyManagementProviderStatus, error)
+	IsRefreshableFunc   func() bool
 }
 
 func (c *TestKeyManagementProvider) GetCertificates(_ context.Context) (map[keymanagementprovider.KMPMapKey][]*x509.Certificate, keymanagementprovider.KeyManagementProviderStatus, error) {
+	if c.GetCertificatesFunc != nil {
+		return c.GetCertificatesFunc(context.Background())
+	}
 	return c.certificates, c.status, c.err
 }
 
 func (c *TestKeyManagementProvider) GetKeys(_ context.Context) (map[keymanagementprovider.KMPMapKey]crypto.PublicKey, keymanagementprovider.KeyManagementProviderStatus, error) {
+	if c.GetKeysFunc != nil {
+		return c.GetKeysFunc(context.Background())
+	}
 	return c.keys, c.status, c.err
 }
 
 func (c *TestKeyManagementProvider) IsRefreshable() bool {
-	return true
+	if c.IsRefreshableFunc != nil {
+		return c.IsRefreshableFunc()
+	}
+	return false
 }
diff --git a/pkg/keymanagementprovider/refresh/factory.go b/pkg/keymanagementprovider/refresh/factory.go
index 186951c..eed41e1 100644
--- a/pkg/keymanagementprovider/refresh/factory.go
+++ b/pkg/keymanagementprovider/refresh/factory.go
@@ -21,7 +21,8 @@ var refresherFactories = make(map[string]RefresherFactory)
 
 type RefresherFactory interface {
 	// Create creates a new instance of the refresher using the provided configuration
-	Create(config map[string]interface{}) (Refresher, error)
+	// Create(config map[string]interface{}) (Refresher, error)
+	Create(config RefresherConfig) (Refresher, error)
 }
 
 // Refresher is an interface that defines methods to be implemented by a each refresher
@@ -37,17 +38,10 @@ func Register(name string, factory RefresherFactory) {
 }
 
 // CreateRefresherFromConfig creates a new instance of the refresher using the provided configuration
-func CreateRefresherFromConfig(refresherConfig map[string]interface{}) (Refresher, error) {
-	refresherType, ok := refresherConfig["type"].(string)
+func CreateRefresherFromConfig(refresherConfig RefresherConfig) (Refresher, error) {
+	factory, ok := refresherFactories[refresherConfig.RefresherType]
 	if !ok {
-		return nil, fmt.Errorf("refresher type is not a string")
-	}
-	if !ok || refresherType == "" {
-		return nil, fmt.Errorf("refresher type cannot be empty")
-	}
-	factory, ok := refresherFactories[refresherType]
-	if !ok {
-		return nil, fmt.Errorf("refresher factory with name %s not found", refresherType)
+		return nil, fmt.Errorf("refresher factory with name %s not found", refresherConfig.RefresherType)
 	}
 	return factory.Create(refresherConfig)
 }
diff --git a/pkg/keymanagementprovider/refresh/kubeRefresh.go b/pkg/keymanagementprovider/refresh/kubeRefresh.go
index acd967e..895cb7d 100644
--- a/pkg/keymanagementprovider/refresh/kubeRefresh.go
+++ b/pkg/keymanagementprovider/refresh/kubeRefresh.go
@@ -18,28 +18,23 @@ package refresh
 
 import (
 	"context"
-	"encoding/json"
 	"fmt"
 	"maps"
 	"time"
 
-	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
 	re "github.com/ratify-project/ratify/errors"
-	"github.com/ratify-project/ratify/internal/constants"
-	cutils "github.com/ratify-project/ratify/pkg/controllers/utils"
 	kmp "github.com/ratify-project/ratify/pkg/keymanagementprovider"
 	"github.com/sirupsen/logrus"
-	apierrors "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
 	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 type KubeRefresher struct {
-	client.Client
-	Request ctrl.Request
-	Result  ctrl.Result
+	Provider                kmp.KeyManagementProvider
+	ProviderType            string
+	ProviderRefreshInterval string
+	Resource                string
+	Result                  ctrl.Result
+	Status                  kmp.KeyManagementProviderStatus
 }
 
 // Register registers the kubeRefresher factory
@@ -51,99 +46,45 @@ func init() {
 func (kr *KubeRefresher) Refresh(ctx context.Context) error {
 	logger := logrus.WithContext(ctx)
 
-	var resource = kr.Request.Name
-	var keyManagementProvider configv1beta1.KeyManagementProvider
-
-	logger.Infof("reconciling cluster key management provider '%v'", resource)
-
-	if err := kr.Get(ctx, kr.Request.NamespacedName, &keyManagementProvider); err != nil {
-		if apierrors.IsNotFound(err) {
-			logger.Infof("deletion detected, removing key management provider %v", resource)
-			kmp.DeleteResourceFromMap(resource)
-		} else {
-			logger.Error(err, "unable to fetch key management provider")
-		}
-
-		kr.Result = ctrl.Result{}
-
-		return client.IgnoreNotFound(err)
-	}
-
-	lastFetchedTime := metav1.Now()
-	isFetchSuccessful := false
-
-	// get certificate store list to check if certificate store is configured
-	// TODO: remove check in v2.0.0+
-	var certificateStoreList configv1beta1.CertificateStoreList
-	if err := kr.List(ctx, &certificateStoreList); err != nil {
-		logger.Error(err, "unable to list certificate stores")
-		kr.Result = ctrl.Result{}
-		return err
-	}
-
-	if len(certificateStoreList.Items) > 0 {
-		// Note: for backwards compatibility in upgrade scenarios, Ratify will only log a warning statement.
-		logger.Warn("Certificate Store already exists. Key management provider and certificate store should not be configured together. Please migrate to key management provider and delete certificate store.")
-	}
-
-	provider, err := cutils.SpecToKeyManagementProvider(keyManagementProvider.Spec.Parameters.Raw, keyManagementProvider.Spec.Type)
-	if err != nil {
-		kmpErr := re.ErrorCodePluginInitFailure.WithError(err).WithDetail("Failed to create key management provider from CR")
-
-		kmp.SetCertificateError(resource, kmpErr)
-		kmp.SetKeyError(resource, kmpErr)
-		writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
-		kr.Request = ctrl.Request{}
-		return kmpErr
-	}
-
 	// fetch certificates and store in map
-	certificates, certAttributes, err := provider.GetCertificates(ctx)
+	certificates, certAttributes, err := kr.Provider.GetCertificates(ctx)
 	if err != nil {
-		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch certificates from key management provider [%s] of type [%s]", resource, keyManagementProvider.Spec.Type))
-
-		kmp.SetCertificateError(resource, err)
-		writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
-		kr.Request = ctrl.Request{}
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch certificates from key management provider [%s] of type [%s]", kr.Resource, kr.ProviderType))
+		kmp.SetCertificateError(kr.Resource, err)
 		return kmpErr
 	}
 
 	// fetch keys and store in map
-	keys, keyAttributes, err := provider.GetKeys(ctx)
+	keys, keyAttributes, err := kr.Provider.GetKeys(ctx)
 	if err != nil {
-		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch keys from key management provider [%s] of type [%s]", resource, keyManagementProvider.Spec.Type))
-
-		kmp.SetKeyError(resource, kmpErr)
-		writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
-		kr.Request = ctrl.Request{}
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch keys from key management provider [%s] of type [%s]", kr.Resource, kr.ProviderType))
+		kmp.SetKeyError(kr.Resource, err)
 		return kmpErr
 	}
-	kmp.SaveSecrets(resource, keyManagementProvider.Spec.Type, keys, certificates)
+
+	kmp.SaveSecrets(kr.Resource, kr.ProviderType, keys, certificates)
 	// merge certificates and keys status into one
 	maps.Copy(keyAttributes, certAttributes)
-	isFetchSuccessful = true
-	writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, nil, lastFetchedTime, keyAttributes)
+	kr.Status = keyAttributes
 
-	logger.Infof("%v certificate(s) & %v key(s) fetched for key management provider %v", len(certificates), len(keys), resource)
+	logger.Infof("%v certificate(s) & %v key(s) fetched for key management provider %v", len(certificates), len(keys), kr.Resource)
 
-	// returning empty result and no error to indicate we’ve successfully reconciled this object
+	// Resource is not refreshable, returning empty result and no error to indicate we’ve successfully reconciled this object
 	// will not reconcile again unless resource is recreated
-	if !provider.IsRefreshable() {
-		kr.Request = ctrl.Request{}
+	if !kr.Provider.IsRefreshable() {
 		return nil
 	}
 
 	// if interval is not set, disable refresh
-	if keyManagementProvider.Spec.RefreshInterval == "" {
-		kr.Result = ctrl.Result{}
+	if kr.ProviderRefreshInterval == "" {
 		return nil
 	}
+
 	// resource is refreshable, requeue after interval
-	intervalDuration, err := time.ParseDuration(keyManagementProvider.Spec.RefreshInterval)
+	intervalDuration, err := time.ParseDuration(kr.ProviderRefreshInterval)
 	if err != nil {
-		logger.Error(err, "unable to parse interval duration")
-		kr.Result = ctrl.Result{}
-		return err
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to parse interval duration for key management provider [%s] of type [%s]", kr.Resource, kr.ProviderType))
+		return kmpErr
 	}
 
 	logger.Info("Reconciled KeyManagementProvider", "intervalDuration", intervalDuration)
@@ -157,57 +98,16 @@ func (kr *KubeRefresher) GetResult() interface{} {
 	return kr.Result
 }
 
-// Create creates a new KubeRefresher instance
-func (kr *KubeRefresher) Create(config map[string]interface{}) (Refresher, error) {
-	client, ok := config["client"].(client.Client)
-	if !ok {
-		return nil, fmt.Errorf("client is required in config")
-	}
-
-	request, ok := config["request"].(ctrl.Request)
-	if !ok {
-		return nil, fmt.Errorf("request is required in config")
-	}
+func (kr *KubeRefresher) GetStatus() interface{} {
+	return kr.Status
+}
 
+// Create creates a new KubeRefresher instance
+func (kr *KubeRefresher) Create(config RefresherConfig) (Refresher, error) {
 	return &KubeRefresher{
-		Client:  client,
-		Request: request,
+		Provider:                config.Provider,
+		ProviderType:            config.ProviderType,
+		ProviderRefreshInterval: config.ProviderRefreshInterval,
+		Resource:                config.Resource,
 	}, nil
 }
-
-func writeKMProviderStatus(ctx context.Context, r client.StatusClient, keyManagementProvider *configv1beta1.KeyManagementProvider, logger *logrus.Entry, isSuccess bool, err *re.Error, operationTime metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
-	if isSuccess {
-		updateKMProviderSuccessStatus(keyManagementProvider, &operationTime, kmProviderStatus)
-	} else {
-		updateKMProviderErrorStatus(keyManagementProvider, err, &operationTime)
-	}
-	if statusErr := r.Status().Update(ctx, keyManagementProvider); statusErr != nil {
-		logger.Error(statusErr, ",unable to update key management provider error status")
-	}
-}
-
-// updateKMProviderErrorStatus updates the key management provider status with error, brief error and last fetched time
-func updateKMProviderErrorStatus(keyManagementProvider *configv1beta1.KeyManagementProvider, err *re.Error, operationTime *metav1.Time) {
-	keyManagementProvider.Status.IsSuccess = false
-	keyManagementProvider.Status.Error = err.Error()
-	keyManagementProvider.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
-	keyManagementProvider.Status.LastFetchedTime = operationTime
-}
-
-// updateKMProviderSuccessStatus updates the key management provider status if status argument is non nil
-// Success status includes last fetched time and other provider-specific properties
-func updateKMProviderSuccessStatus(keyManagementProvider *configv1beta1.KeyManagementProvider, lastOperationTime *metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
-	keyManagementProvider.Status.IsSuccess = true
-	keyManagementProvider.Status.Error = ""
-	keyManagementProvider.Status.BriefError = ""
-	keyManagementProvider.Status.LastFetchedTime = lastOperationTime
-
-	if kmProviderStatus != nil {
-		jsonString, _ := json.Marshal(kmProviderStatus)
-
-		raw := runtime.RawExtension{
-			Raw: jsonString,
-		}
-		keyManagementProvider.Status.Properties = raw
-	}
-}
diff --git a/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced.go b/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced.go
deleted file mode 100644
index 8bd4ade..0000000
--- a/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced.go
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
-Copyright The Ratify Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-package refresh
-
-import (
-	"context"
-	"encoding/json"
-	"fmt"
-	"maps"
-	"time"
-
-	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
-	re "github.com/ratify-project/ratify/errors"
-	"github.com/ratify-project/ratify/internal/constants"
-	cutils "github.com/ratify-project/ratify/pkg/controllers/utils"
-	kmp "github.com/ratify-project/ratify/pkg/keymanagementprovider"
-	"github.com/sirupsen/logrus"
-	apierrors "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-type KubeRefresherNamespaced struct {
-	client.Client
-	Request ctrl.Request
-	Result  ctrl.Result
-}
-
-// Register registers the kubeRefresherNamespaced factory
-func init() {
-	Register(KubeRefresherNamespacedType, &KubeRefresherNamespaced{})
-}
-
-// Refresh the certificates/keys for the key management provider by calling the GetCertificates and GetKeys methods
-func (kr *KubeRefresherNamespaced) Refresh(ctx context.Context) error {
-	logger := logrus.WithContext(ctx)
-
-	var resource = kr.Request.NamespacedName.String()
-	var keyManagementProvider configv1beta1.NamespacedKeyManagementProvider
-
-	logger.Infof("reconciling namespaced key management provider '%v'", resource)
-
-	if err := kr.Get(ctx, kr.Request.NamespacedName, &keyManagementProvider); err != nil {
-		if apierrors.IsNotFound(err) {
-			logger.Infof("deletion detected, removing key management provider %v", resource)
-			kmp.DeleteResourceFromMap(resource)
-		} else {
-			logger.Error(err, "unable to fetch key management provider")
-		}
-
-		kr.Result = ctrl.Result{}
-
-		return client.IgnoreNotFound(err)
-	}
-
-	lastFetchedTime := metav1.Now()
-	isFetchSuccessful := false
-
-	// get certificate store list to check if certificate store is configured
-	// TODO: remove check in v2.0.0+
-	var certificateStoreList configv1beta1.CertificateStoreList
-	if err := kr.List(ctx, &certificateStoreList); err != nil {
-		logger.Error(err, "unable to list certificate stores")
-		kr.Result = ctrl.Result{}
-		return err
-	}
-	// if certificate store is configured, return error. Only one of certificate store and key management provider can be configured
-	if len(certificateStoreList.Items) > 0 {
-		// Note: for backwards compatibility in upgrade scenarios, Ratify will only log a warning statement.
-		logger.Warn("Certificate Store already exists. Key management provider and certificate store should not be configured together. Please migrate to key management provider and delete certificate store.")
-	}
-
-	provider, err := cutils.SpecToKeyManagementProvider(keyManagementProvider.Spec.Parameters.Raw, keyManagementProvider.Spec.Type)
-	if err != nil {
-		kmpErr := re.ErrorCodePluginInitFailure.WithError(err).WithDetail("Failed to create key management provider from CR")
-
-		kmp.SetCertificateError(resource, kmpErr)
-		kmp.SetKeyError(resource, kmpErr)
-		writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
-		kr.Result = ctrl.Result{}
-		return kmpErr
-	}
-
-	// fetch certificates and store in map
-	certificates, certAttributes, err := provider.GetCertificates(ctx)
-	if err != nil {
-		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch certificates from key management provider: %s of type: %s", resource, keyManagementProvider.Spec.Type))
-
-		kmp.SetCertificateError(resource, kmpErr)
-		writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
-		kr.Result = ctrl.Result{}
-		return kmpErr
-	}
-
-	// fetch keys and store in map
-	keys, keyAttributes, err := provider.GetKeys(ctx)
-	if err != nil {
-		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch keys from key management provider: %s of type: %s", resource, keyManagementProvider.Spec.Type))
-
-		kmp.SetKeyError(resource, kmpErr)
-		writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
-		kr.Result = ctrl.Result{}
-		return kmpErr
-	}
-	kmp.SaveSecrets(resource, keyManagementProvider.Spec.Type, keys, certificates)
-	// merge certificates and keys status into one
-	maps.Copy(keyAttributes, certAttributes)
-	isFetchSuccessful = true
-	writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, nil, lastFetchedTime, keyAttributes)
-
-	logger.Infof("%v certificate(s) & %v key(s) fetched for key management provider %v", len(certificates), len(keys), resource)
-
-	if !provider.IsRefreshable() {
-		kr.Result = ctrl.Result{}
-		return nil
-	}
-
-	// if interval is not set, disable refresh
-	if keyManagementProvider.Spec.RefreshInterval == "" {
-		kr.Result = ctrl.Result{}
-		return nil
-	}
-
-	intervalDuration, err := time.ParseDuration(keyManagementProvider.Spec.RefreshInterval)
-	if err != nil {
-		logger.Error(err, "unable to parse interval duration")
-		kr.Result = ctrl.Result{}
-		return err
-	}
-
-	logger.Info("Reconciled KeyManagementProvider", "intervalDuration", intervalDuration)
-	kr.Result = ctrl.Result{RequeueAfter: intervalDuration}
-
-	return nil
-}
-
-// GetResult returns the result of the refresh as ctrl.Result
-func (kr *KubeRefresherNamespaced) GetResult() interface{} {
-	return kr.Result
-}
-
-// Create creates a new instance of KubeRefresherNamespaced
-func (kr *KubeRefresherNamespaced) Create(config map[string]interface{}) (Refresher, error) {
-	client, ok := config["client"].(client.Client)
-	if !ok {
-		return nil, fmt.Errorf("client is required in config")
-	}
-
-	request, ok := config["request"].(ctrl.Request)
-	if !ok {
-		return nil, fmt.Errorf("request is required in config")
-	}
-
-	return &KubeRefresherNamespaced{
-		Client:  client,
-		Request: request,
-	}, nil
-}
-
-// writeKMProviderStatus updates the status of the key management provider resource
-func writeKMProviderStatusNamespaced(ctx context.Context, r client.StatusClient, keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, logger *logrus.Entry, isSuccess bool, err *re.Error, operationTime metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
-	if isSuccess {
-		updateKMProviderSuccessStatusNamespaced(keyManagementProvider, &operationTime, kmProviderStatus)
-	} else {
-		updateKMProviderErrorStatusNamespaced(keyManagementProvider, err, &operationTime)
-	}
-	if statusErr := r.Status().Update(ctx, keyManagementProvider); statusErr != nil {
-		logger.Error(statusErr, ",unable to update key management provider error status")
-	}
-}
-
-// updateKMProviderErrorStatus updates the key management provider status with error, brief error and last fetched time
-func updateKMProviderErrorStatusNamespaced(keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, err *re.Error, operationTime *metav1.Time) {
-	keyManagementProvider.Status.IsSuccess = false
-	keyManagementProvider.Status.Error = err.Error()
-	keyManagementProvider.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
-	keyManagementProvider.Status.LastFetchedTime = operationTime
-}
-
-// updateKMProviderSuccessStatus updates the key management provider status if status argument is non nil
-// Success status includes last fetched time and other provider-specific properties
-func updateKMProviderSuccessStatusNamespaced(keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, lastOperationTime *metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
-	keyManagementProvider.Status.IsSuccess = true
-	keyManagementProvider.Status.Error = ""
-	keyManagementProvider.Status.BriefError = ""
-	keyManagementProvider.Status.LastFetchedTime = lastOperationTime
-
-	if kmProviderStatus != nil {
-		jsonString, _ := json.Marshal(kmProviderStatus)
-
-		raw := runtime.RawExtension{
-			Raw: jsonString,
-		}
-		keyManagementProvider.Status.Properties = raw
-	}
-}
diff --git a/pkg/keymanagementprovider/refresh/refresh.go b/pkg/keymanagementprovider/refresh/refresh.go
index 78e32b1..36e05e2 100644
--- a/pkg/keymanagementprovider/refresh/refresh.go
+++ b/pkg/keymanagementprovider/refresh/refresh.go
@@ -18,11 +18,12 @@ package refresh
 
 import (
 	"context"
+
+	"github.com/ratify-project/ratify/pkg/keymanagementprovider"
 )
 
 const (
-	KubeRefresherType           = "kubeRefresher"
-	KubeRefresherNamespacedType = "kubeRefresherNamespaced"
+	KubeRefresherType = "kubeRefresher"
 )
 
 // Refresher is an interface that defines methods to be implemented by a each refresher
@@ -31,4 +32,15 @@ type Refresher interface {
 	Refresh(ctx context.Context) error
 	// GetResult is a method that returns the result of the refresh
 	GetResult() interface{}
+	// GetStatus is a method that returns the status of the refresh
+	GetStatus() interface{}
+}
+
+// RefresherConfig is a struct that holds the configuration for a refresher
+type RefresherConfig struct {
+	RefresherType           string                                      // RefresherType is the type of the refresher
+	Provider                keymanagementprovider.KeyManagementProvider // Provider is the key management provider
+	ProviderType            string                                      // ProviderType is the type of the provider
+	ProviderRefreshInterval string                                      // ProviderRefreshInterval is the refresh interval for the provider
+	Resource                string                                      // Resource is the resource to be refreshed
 }


Test patch:
diff --git a/.github/workflows/e2e-aks.yml b/.github/workflows/e2e-aks.yml
index 90799a2..f6a2c1f 100644
--- a/.github/workflows/e2e-aks.yml
+++ b/.github/workflows/e2e-aks.yml
@@ -7,14 +7,14 @@ on:
   workflow_call:
     inputs:
       k8s_version:
-        description: 'Kubernetes version'
+        description: "Kubernetes version"
         required: true
-        default: '1.29.2'
+        default: "1.29.2"
         type: string
       gatekeeper_version:
-        description: 'Gatekeeper version'
+        description: "Gatekeeper version"
         required: true
-        default: '3.17.0'
+        default: "3.17.0"
         type: string
 
 jobs:
@@ -37,7 +37,7 @@ jobs:
       - name: Set up Go 1.22
         uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
         with:
-          go-version: '1.22'
+          go-version: "1.22"
       - name: Az CLI login
         uses: azure/login@6c251865b4e6290e7b78be643ea2d005bc51f69a # v2.1.1
         with:
@@ -69,4 +69,4 @@ jobs:
         with:
           name: e2e-logs-aks-${{ inputs.k8s_version }}-${{ inputs.gatekeeper_version }}
           path: |
-            logs-*.json
\ No newline at end of file
+            logs-*.json
diff --git a/.github/workflows/e2e-cli.yml b/.github/workflows/e2e-cli.yml
index 895d77f..6703844 100644
--- a/.github/workflows/e2e-cli.yml
+++ b/.github/workflows/e2e-cli.yml
@@ -29,8 +29,7 @@ jobs:
         uses: apache/skywalking-eyes/dependency@cd7b195c51fd3d6ad52afceb760719ddc6b3ee91
         with:
           config: .github/licenserc.yml
-          flags:
-            --weak-compatible=true
+          flags: --weak-compatible=true
   build:
     runs-on: ubuntu-latest
     steps:
@@ -89,8 +88,8 @@ jobs:
         with:
           token: ${{ secrets.CODECOV_TOKEN }}
   markdown-link-check:
-      runs-on: ubuntu-latest
-      steps:
+    runs-on: ubuntu-latest
+    steps:
       - name: Harden Runner
         uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
@@ -103,7 +102,7 @@ jobs:
       - name: Run link check
         uses: gaurav-nelson/github-action-markdown-link-check@d53a906aa6b22b8979d33bc86170567e619495ec #3.10.3
         with:
-          use-quiet-mode: 'no'
-          use-verbose-mode: 'yes'
-          config-file: '.github/workflows/markdown.links.config.json'
-          folder-path: 'docs/'
\ No newline at end of file
+          use-quiet-mode: "no"
+          use-verbose-mode: "yes"
+          config-file: ".github/workflows/markdown.links.config.json"
+          folder-path: "docs/"
diff --git a/.github/workflows/e2e-k8s.yml b/.github/workflows/e2e-k8s.yml
index 22eaa69..717ff93 100644
--- a/.github/workflows/e2e-k8s.yml
+++ b/.github/workflows/e2e-k8s.yml
@@ -7,14 +7,14 @@ on:
   workflow_call:
     inputs:
       k8s_version:
-        description: 'Kubernetes version'
+        description: "Kubernetes version"
         required: true
-        default: '1.29.2'
+        default: "1.29.2"
         type: string
       gatekeeper_version:
-        description: 'Gatekeeper version'
+        description: "Gatekeeper version"
         required: true
-        default: '3.17.0'
+        default: "3.17.0"
         type: string
 
 jobs:
@@ -35,7 +35,7 @@ jobs:
       - name: Set up Go 1.22
         uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
         with:
-          go-version: '1.22'
+          go-version: "1.22"
 
       - name: Bootstrap e2e
         run: |
@@ -70,4 +70,4 @@ jobs:
         with:
           name: e2e-logs-${{ inputs.k8s_version }}-${{ inputs.gatekeeper_version }}
           path: |
-            logs-*.json
\ No newline at end of file
+            logs-*.json
diff --git a/pkg/controllers/clusterresource/keymanagementprovider_controller_test.go b/pkg/controllers/clusterresource/keymanagementprovider_controller_test.go
index d4129e2..60254ee 100644
--- a/pkg/controllers/clusterresource/keymanagementprovider_controller_test.go
+++ b/pkg/controllers/clusterresource/keymanagementprovider_controller_test.go
@@ -18,82 +18,357 @@ package clusterresource
 import (
 	"context"
 	"errors"
+	"fmt"
 	"reflect"
 	"testing"
 
-	"github.com/ratify-project/ratify/pkg/keymanagementprovider/refresh"
+	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	"github.com/ratify-project/ratify/pkg/keymanagementprovider"
+	"github.com/ratify-project/ratify/pkg/keymanagementprovider/mocks"
 	test "github.com/ratify-project/ratify/pkg/utils"
+	"github.com/sirupsen/logrus"
+
+	re "github.com/ratify-project/ratify/errors"
+	kmp "github.com/ratify-project/ratify/pkg/keymanagementprovider"
+	"github.com/ratify-project/ratify/pkg/keymanagementprovider/refresh"
+
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/apimachinery/pkg/types"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 )
 
-func TestKeyManagementProviderReconciler_ReconcileWithConfig(t *testing.T) {
+func init() {
+	refresh.Register("mockRefresher", &MockRefresher{})
+}
+
+type MockRefresher struct {
+	Result       ctrl.Result
+	RefreshError bool
+	ResultError  bool
+	StatusError  bool
+	Status       kmp.KeyManagementProviderStatus
+}
+
+func (mr *MockRefresher) Refresh(_ context.Context) error {
+	if mr.RefreshError {
+		return errors.New("error from refresh")
+	}
+	return nil
+}
+
+func (mr *MockRefresher) GetResult() interface{} {
+	if mr.ResultError {
+		return errors.New("error from result")
+	}
+	return mr.Result
+}
+
+func (mr *MockRefresher) GetStatus() interface{} {
+	if mr.StatusError {
+		return errors.New("error from status")
+	}
+	return mr.Status
+}
+
+func (mr *MockRefresher) Create(config refresh.RefresherConfig) (refresh.Refresher, error) {
+	if config.Resource == "refreshError" {
+		return &MockRefresher{
+			RefreshError: true,
+		}, nil
+	}
+	if config.Resource == "resultError" {
+		return &MockRefresher{
+			ResultError: true,
+		}, nil
+	}
+	if config.Resource == "statusError" {
+		return &MockRefresher{
+			StatusError: true,
+		}, nil
+	}
+	return &MockRefresher{}, nil
+}
+
+func TestKeyManagementProviderReconciler_ReconcileWithType(t *testing.T) {
 	tests := []struct {
-		name              string
-		refresherType     string
-		createConfigError bool
-		refreshError      bool
-		expectedError     bool
+		name           string
+		clientGetFunc  func(_ context.Context, key types.NamespacedName, obj client.Object) error
+		clientListFunc func(_ context.Context, list client.ObjectList) error
+		resourceName   string
+		refresherType  string
+		expectedResult ctrl.Result
+		expectedError  bool
 	}{
 		{
-			name:              "Successful Reconcile",
-			refresherType:     "mockRefresher",
-			createConfigError: false,
-			refreshError:      false,
-			expectedError:     false,
+			// TODO: Add SetLogger to internal/logger/logger.go to compare log messages
+			// https://maxchadwick.xyz/blog/testing-log-output-in-go-logrus
+			name: "api is not found",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, _ client.Object) error {
+				resource := schema.GroupResource{
+					Group:    "",     // Use an empty string for core resources (like Pod)
+					Resource: "pods", // Resource type, e.g., "pods" for Pod resources
+				}
+				return apierrors.NewNotFound(resource, "test")
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			refresherType:  "mockRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  false,
+		},
+		{
+			name: "unable to fetch key management provider",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, _ client.Object) error {
+				return fmt.Errorf("unable to fetch key management provider")
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			refresherType:  "mockRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  false,
+		},
+		{
+			name: "unable to list certificate stores",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, _ client.Object) error {
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return fmt.Errorf("unable to list certificate stores")
+			},
+			refresherType:  "mockRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  true,
+		},
+		{
+			name: "certificate store already exists",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.KeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.KeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, list client.ObjectList) error {
+				certStoreList, ok := list.(*configv1beta1.CertificateStoreList)
+				if !ok {
+					return errors.New("expected CertificateStoreList")
+				}
+
+				certStoreList.Items = []configv1beta1.CertificateStore{
+					{
+						ObjectMeta: metav1.ObjectMeta{
+							Name: "test",
+						},
+					},
+				}
+				return nil
+			},
+			refresherType:  "mockRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  false,
+		},
+		{
+			name: "cutils.SpecToKeyManagementProvider failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.KeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			refresherType:  "mockRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  true,
+		},
+		{
+			name: "refresh.CreateRefresherFromConfig failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.KeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.KeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			refresherType:  "invalidRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  true,
+		},
+		{
+			name: "refresh.Refresh failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.KeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.KeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceName:   "refreshError",
+			refresherType:  "mockRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  true,
 		},
 		{
-			name:              "Refresher Error",
-			refresherType:     "mockRefresher",
-			createConfigError: false,
-			refreshError:      true,
-			expectedError:     true,
+			name: "refresher.GetResult failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.KeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.KeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceName:   "resultError",
+			refresherType:  "mockRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  true,
 		},
 		{
-			name:              "Invalid Refresher Type",
-			refresherType:     "invalidRefresher",
-			createConfigError: true,
-			refreshError:      false,
-			expectedError:     true,
+			name: "refresher.GetStatus failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.KeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.KeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceName:   "statusError",
+			refresherType:  "mockRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  true,
+		},
+		{
+			name: "successfully reconciled",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.KeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.KeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			refresherType:  "mockRefresher",
+			expectedResult: ctrl.Result{},
+			expectedError:  false,
 		},
 	}
+
 	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			req := ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Name:      "fake-name",
-					Namespace: "fake-namespace",
-				},
-			}
-			scheme, _ := test.CreateScheme()
-			client := fake.NewClientBuilder().WithScheme(scheme).Build()
+		fmt.Println(tt.name)
+		mockClient := mocks.TestClient{
+			GetFunc:  tt.clientGetFunc,
+			ListFunc: tt.clientListFunc,
+		}
+		req := ctrl.Request{
+			NamespacedName: client.ObjectKey{
+				Name:      tt.resourceName,
+				Namespace: "test",
+			},
+		}
+		scheme, _ := test.CreateScheme()
 
-			r := &KeyManagementProviderReconciler{
-				Client: client,
-				Scheme: runtime.NewScheme(),
-			}
+		r := &KeyManagementProviderReconciler{
+			Client: &mockClient,
+			Scheme: scheme,
+		}
 
-			refresherConfig := map[string]interface{}{
-				"type":              tt.refresherType,
-				"client":            client,
-				"request":           req,
-				"createConfigError": tt.createConfigError,
-				"refreshError":      tt.refreshError,
-				"shouldError":       tt.expectedError,
-			}
+		result, err := r.ReconcileWithType(context.Background(), req, tt.refresherType)
 
-			_, err := r.ReconcileWithConfig(context.TODO(), refresherConfig)
-			if tt.expectedError && err == nil {
-				t.Errorf("Expected error, got nil")
-			}
-			if !tt.expectedError && err != nil {
-				t.Errorf("Expected no error, got %v", err)
-			}
-		})
+		if !reflect.DeepEqual(result, tt.expectedResult) {
+			t.Fatalf("Expected result %v, got %v", tt.expectedResult, result)
+		}
+		if tt.expectedError && err == nil {
+			t.Fatalf("Expected error, got nil")
+		}
 	}
 }
+
 func TestKeyManagementProviderReconciler_Reconcile(t *testing.T) {
 	req := ctrl.Request{
 		NamespacedName: client.ObjectKey{
@@ -124,36 +399,150 @@ func TestKeyManagementProviderReconciler_Reconcile(t *testing.T) {
 	}
 }
 
-type MockRefresher struct {
-	Results           ctrl.Result
-	CreateConfigError bool
-	RefreshError      bool
-	ShouldError       bool
-}
+// TestUpdateErrorStatus tests the updateErrorStatus method
+func TestKMProviderUpdateErrorStatus(t *testing.T) {
+	var parametersString = "{\"certs\":{\"name\":\"certName\"}}"
+	var kmProviderStatus = []byte(parametersString)
 
-func (mr *MockRefresher) Refresh(_ context.Context) error {
-	if mr.RefreshError {
-		return errors.New("refresh error")
+	status := configv1beta1.KeyManagementProviderStatus{
+		IsSuccess: true,
+		Properties: runtime.RawExtension{
+			Raw: kmProviderStatus,
+		},
+	}
+	keyManagementProvider := configv1beta1.KeyManagementProvider{
+		Status: status,
+	}
+	expectedErr := re.ErrorCodeUnknown.WithDetail("it's a long error from unit test")
+	lastFetchedTime := metav1.Now()
+	updateKMProviderErrorStatus(&keyManagementProvider, &expectedErr, &lastFetchedTime)
+
+	if keyManagementProvider.Status.IsSuccess != false {
+		t.Fatalf("Unexpected error, expected isSuccess to be false , actual %+v", keyManagementProvider.Status.IsSuccess)
+	}
+
+	if keyManagementProvider.Status.Error != expectedErr.Error() {
+		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr, keyManagementProvider.Status.Error)
+	}
+	if keyManagementProvider.Status.BriefError != expectedErr.GetConciseError(150) {
+		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr.GetConciseError(150), keyManagementProvider.Status.Error)
+	}
+
+	//make sure properties of last cached cert was not overridden
+	if len(keyManagementProvider.Status.Properties.Raw) == 0 {
+		t.Fatalf("Unexpected properties,  expected %+v, got %+v", parametersString, string(keyManagementProvider.Status.Properties.Raw))
 	}
-	return nil
 }
 
-func (mr *MockRefresher) GetResult() interface{} {
-	return ctrl.Result{}
+// TestKMProviderUpdateSuccessStatus tests the updateSuccessStatus method
+func TestKMProviderUpdateSuccessStatus(t *testing.T) {
+	kmProviderStatus := keymanagementprovider.KeyManagementProviderStatus{}
+	properties := map[string]string{}
+	properties["Name"] = "wabbit"
+	properties["Version"] = "ABC"
+
+	kmProviderStatus["Certificates"] = properties
+
+	lastFetchedTime := metav1.Now()
+
+	status := configv1beta1.KeyManagementProviderStatus{
+		IsSuccess: false,
+		Error:     "error from last operation",
+	}
+	keyManagementProvider := configv1beta1.KeyManagementProvider{
+		Status: status,
+	}
+
+	updateKMProviderSuccessStatus(&keyManagementProvider, &lastFetchedTime, kmProviderStatus)
+
+	if keyManagementProvider.Status.IsSuccess != true {
+		t.Fatalf("Expected isSuccess to be true , actual %+v", keyManagementProvider.Status.IsSuccess)
+	}
+
+	if keyManagementProvider.Status.Error != "" {
+		t.Fatalf("Unexpected error string, actual %+v", keyManagementProvider.Status.Error)
+	}
+
+	//make sure properties of last cached cert was updated
+	if len(keyManagementProvider.Status.Properties.Raw) == 0 {
+		t.Fatalf("Properties should not be empty")
+	}
 }
 
-func (mr *MockRefresher) Create(config map[string]interface{}) (refresh.Refresher, error) {
-	createConfigError := config["createConfigError"].(bool)
-	refreshError := config["refreshError"].(bool)
-	if createConfigError {
-		return nil, errors.New("create error")
+// TestKMProviderUpdateSuccessStatus tests the updateSuccessStatus method with empty properties
+func TestKMProviderUpdateSuccessStatus_emptyProperties(t *testing.T) {
+	lastFetchedTime := metav1.Now()
+	status := configv1beta1.KeyManagementProviderStatus{
+		IsSuccess: false,
+		Error:     "error from last operation",
+	}
+	keyManagementProvider := configv1beta1.KeyManagementProvider{
+		Status: status,
+	}
+
+	updateKMProviderSuccessStatus(&keyManagementProvider, &lastFetchedTime, nil)
+
+	if keyManagementProvider.Status.IsSuccess != true {
+		t.Fatalf("Expected isSuccess to be true , actual %+v", keyManagementProvider.Status.IsSuccess)
+	}
+
+	if keyManagementProvider.Status.Error != "" {
+		t.Fatalf("Unexpected error string, actual %+v", keyManagementProvider.Status.Error)
+	}
+
+	//make sure properties of last cached cert was updated
+	if len(keyManagementProvider.Status.Properties.Raw) != 0 {
+		t.Fatalf("Properties should be empty")
 	}
-	return &MockRefresher{
-		CreateConfigError: createConfigError,
-		RefreshError:      refreshError,
-	}, nil
 }
+func TestWriteKMProviderStatus(t *testing.T) {
+	logger := logrus.WithContext(context.Background())
+	lastFetchedTime := metav1.Now()
+	testCases := []struct {
+		name              string
+		isSuccess         bool
+		kmProvider        *configv1beta1.KeyManagementProvider
+		errString         string
+		expectedErrString string
+		reconciler        client.StatusClient
+	}{
+		{
+			name:       "success status",
+			isSuccess:  true,
+			errString:  "",
+			kmProvider: &configv1beta1.KeyManagementProvider{},
+			reconciler: &test.MockStatusClient{},
+		},
+		{
+			name:              "error status",
+			isSuccess:         false,
+			kmProvider:        &configv1beta1.KeyManagementProvider{},
+			errString:         "a long error string that exceeds the max length of 150 characters",
+			expectedErrString: "UNKNOWN: a long error string that exceeds the max length of 150 characters",
+			reconciler:        &test.MockStatusClient{},
+		},
+		{
+			name:       "status update failed",
+			isSuccess:  true,
+			kmProvider: &configv1beta1.KeyManagementProvider{},
+			reconciler: &test.MockStatusClient{
+				UpdateFailed: true,
+			},
+		},
+	}
 
-func init() {
-	refresh.Register("mockRefresher", &MockRefresher{})
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writeKMProviderStatus(context.Background(), tc.reconciler, tc.kmProvider, logger, tc.isSuccess, &err, lastFetchedTime, nil)
+
+			if tc.kmProvider.Status.IsSuccess != tc.isSuccess {
+				t.Fatalf("Expected isSuccess to be: %+v, actual: %+v", tc.isSuccess, tc.kmProvider.Status.IsSuccess)
+			}
+
+			if tc.kmProvider.Status.Error != tc.expectedErrString {
+				t.Fatalf("Expected Error to be: %+v, actual: %+v", tc.expectedErrString, tc.kmProvider.Status.Error)
+			}
+		})
+	}
 }
diff --git a/pkg/controllers/namespaceresource/keymanagementprovider_controller_test.go b/pkg/controllers/namespaceresource/keymanagementprovider_controller_test.go
index 7e4717a..d934754 100644
--- a/pkg/controllers/namespaceresource/keymanagementprovider_controller_test.go
+++ b/pkg/controllers/namespaceresource/keymanagementprovider_controller_test.go
@@ -18,80 +18,358 @@ package namespaceresource
 import (
 	"context"
 	"errors"
+	"fmt"
 	"reflect"
 	"testing"
 
+	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
+	"github.com/ratify-project/ratify/pkg/keymanagementprovider"
+	kmp "github.com/ratify-project/ratify/pkg/keymanagementprovider"
+	"github.com/ratify-project/ratify/pkg/keymanagementprovider/mocks"
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider/refresh"
 	test "github.com/ratify-project/ratify/pkg/utils"
+	"github.com/sirupsen/logrus"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/apimachinery/pkg/types"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 )
 
-func TestKeyManagementProviderReconciler_ReconcileWithConfig(t *testing.T) {
+func init() {
+	refresh.Register("mockRefresher", &MockRefresher{})
+}
+
+type MockRefresher struct {
+	Result       ctrl.Result
+	RefreshError bool
+	ResultError  bool
+	StatusError  bool
+	Status       kmp.KeyManagementProviderStatus
+}
+
+func (mr *MockRefresher) Refresh(_ context.Context) error {
+	if mr.RefreshError {
+		return errors.New("error from refresh")
+	}
+	return nil
+}
+
+func (mr *MockRefresher) GetResult() interface{} {
+	if mr.ResultError {
+		return errors.New("error from result")
+	}
+	return mr.Result
+}
+
+func (mr *MockRefresher) GetStatus() interface{} {
+	if mr.StatusError {
+		return errors.New("error from status")
+	}
+	return mr.Status
+}
+
+func (mr *MockRefresher) Create(config refresh.RefresherConfig) (refresh.Refresher, error) {
+	if config.Resource == "refreshError/test" {
+		return &MockRefresher{
+			RefreshError: true,
+		}, nil
+	}
+	if config.Resource == "resultError/test" {
+		return &MockRefresher{
+			ResultError: true,
+		}, nil
+	}
+	if config.Resource == "statusError/test" {
+		return &MockRefresher{
+			StatusError: true,
+		}, nil
+	}
+	return &MockRefresher{}, nil
+}
+func TestKeyManagementProviderReconciler_ReconcileWithType(t *testing.T) {
 	tests := []struct {
 		name              string
+		clientGetFunc     func(_ context.Context, key types.NamespacedName, obj client.Object) error
+		clientListFunc    func(_ context.Context, list client.ObjectList) error
+		resourceNamespace string
 		refresherType     string
-		createConfigError bool
-		refreshError      bool
+		expectedResult    ctrl.Result
 		expectedError     bool
 	}{
 		{
-			name:              "Successful Reconcile",
+			// TODO: Add SetLogger to internal/logger/logger.go to compare log messages
+			// https://maxchadwick.xyz/blog/testing-log-output-in-go-logrus
+			name: "api is not found",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, _ client.Object) error {
+				resource := schema.GroupResource{
+					Group:    "",     // Use an empty string for core resources (like Pod)
+					Resource: "pods", // Resource type, e.g., "pods" for Pod resources
+				}
+				return apierrors.NewNotFound(resource, "test")
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceNamespace: "test",
+			refresherType:     "mockRefresher",
+			expectedResult:    ctrl.Result{},
+			expectedError:     false,
+		},
+		{
+			name: "unable to fetch key management provider",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, _ client.Object) error {
+				return fmt.Errorf("unable to fetch key management provider")
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceNamespace: "test",
 			refresherType:     "mockRefresher",
-			createConfigError: false,
-			refreshError:      false,
+			expectedResult:    ctrl.Result{},
 			expectedError:     false,
 		},
 		{
-			name:              "Refresher Error",
+			name: "unable to list certificate stores",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, _ client.Object) error {
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return fmt.Errorf("unable to list certificate stores")
+			},
+			resourceNamespace: "test",
 			refresherType:     "mockRefresher",
-			createConfigError: false,
-			refreshError:      true,
+			expectedResult:    ctrl.Result{},
 			expectedError:     true,
 		},
 		{
-			name:              "Invalid Refresher Type",
+			name: "certificate store already exists",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.NamespacedKeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.NamespacedKeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, list client.ObjectList) error {
+				certStoreList, ok := list.(*configv1beta1.CertificateStoreList)
+				if !ok {
+					return errors.New("expected CertificateStoreList")
+				}
+
+				certStoreList.Items = []configv1beta1.CertificateStore{
+					{
+						ObjectMeta: metav1.ObjectMeta{
+							Name: "test",
+						},
+					},
+				}
+				return nil
+			},
+			resourceNamespace: "test",
+			refresherType:     "mockRefresher",
+			expectedResult:    ctrl.Result{},
+			expectedError:     false,
+		},
+		{
+			name: "cutils.SpecToKeyManagementProvider failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.NamespacedKeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceNamespace: "test",
+			refresherType:     "mockRefresher",
+			expectedResult:    ctrl.Result{},
+			expectedError:     true,
+		},
+		{
+			name: "refresh.CreateRefresherFromConfig failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.NamespacedKeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.NamespacedKeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceNamespace: "test",
 			refresherType:     "invalidRefresher",
-			createConfigError: true,
-			refreshError:      false,
+			expectedResult:    ctrl.Result{},
+			expectedError:     true,
+		},
+		{
+			name: "refresh.Refresh failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.NamespacedKeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.NamespacedKeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceNamespace: "refreshError",
+			refresherType:     "mockRefresher",
+			expectedResult:    ctrl.Result{},
+			expectedError:     true,
+		},
+		{
+			name: "refresher.GetResult failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.NamespacedKeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.NamespacedKeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceNamespace: "resultError",
+			refresherType:     "mockRefresher",
+			expectedResult:    ctrl.Result{},
+			expectedError:     true,
+		},
+		{
+			name: "refresher.GetStatus failed",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.NamespacedKeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.NamespacedKeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceNamespace: "statusError",
+			refresherType:     "mockRefresher",
+			expectedResult:    ctrl.Result{},
 			expectedError:     true,
 		},
+		{
+			name: "successfully reconciled",
+			clientGetFunc: func(_ context.Context, _ types.NamespacedName, obj client.Object) error {
+				getKMP, ok := obj.(*configv1beta1.NamespacedKeyManagementProvider)
+				if !ok {
+					return errors.New("expected KeyManagementProvider")
+				}
+				getKMP.ObjectMeta = metav1.ObjectMeta{
+					Namespace: "test",
+					Name:      "test",
+				}
+				getKMP.Spec = configv1beta1.NamespacedKeyManagementProviderSpec{
+					Type: "inline",
+					Parameters: runtime.RawExtension{
+						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+					},
+				}
+				return nil
+			},
+			clientListFunc: func(_ context.Context, _ client.ObjectList) error {
+				return nil
+			},
+			resourceNamespace: "test",
+			refresherType:     "mockRefresher",
+			expectedResult:    ctrl.Result{},
+			expectedError:     false,
+		},
 	}
+
 	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			req := ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Name:      "fake-name",
-					Namespace: "fake-namespace",
-				},
-			}
-			scheme, _ := test.CreateScheme()
-			client := fake.NewClientBuilder().WithScheme(scheme).Build()
+		fmt.Println(tt.name)
+		mockClient := mocks.TestClient{
+			GetFunc:  tt.clientGetFunc,
+			ListFunc: tt.clientListFunc,
+		}
+		req := ctrl.Request{
+			NamespacedName: client.ObjectKey{
+				Name:      "test",
+				Namespace: tt.resourceNamespace,
+			},
+		}
+		scheme, _ := test.CreateScheme()
 
-			r := &KeyManagementProviderReconciler{
-				Client: client,
-				Scheme: runtime.NewScheme(),
-			}
+		r := &KeyManagementProviderReconciler{
+			Client: &mockClient,
+			Scheme: scheme,
+		}
 
-			refresherConfig := map[string]interface{}{
-				"type":              tt.refresherType,
-				"client":            client,
-				"request":           req,
-				"createConfigError": tt.createConfigError,
-				"refreshError":      tt.refreshError,
-				"shouldError":       tt.expectedError,
-			}
+		result, err := r.ReconcileWithType(context.Background(), req, tt.refresherType)
 
-			_, err := r.ReconcileWithConfig(context.TODO(), refresherConfig)
-			if tt.expectedError && err == nil {
-				t.Errorf("Expected error, got nil")
-			}
-			if !tt.expectedError && err != nil {
-				t.Errorf("Expected no error, got %v", err)
-			}
-		})
+		if !reflect.DeepEqual(result, tt.expectedResult) {
+			t.Fatalf("Expected result %v, got %v", tt.expectedResult, result)
+		}
+		if tt.expectedError && err == nil {
+			t.Fatalf("Expected error, got nil")
+		}
 	}
 }
 
@@ -124,37 +402,148 @@ func TestKeyManagementProviderReconciler_Reconcile(t *testing.T) {
 		t.Errorf("Expected result %v, got %v", expectedResult, result)
 	}
 }
+func TestKMProviderUpdateErrorStatusNamespaced(t *testing.T) {
+	var parametersString = "{\"certs\":{\"name\":\"certName\"}}"
+	var kmProviderStatus = []byte(parametersString)
 
-type MockRefresher struct {
-	Results           ctrl.Result
-	CreateConfigError bool
-	RefreshError      bool
-	ShouldError       bool
-}
+	status := configv1beta1.NamespacedKeyManagementProviderStatus{
+		IsSuccess: true,
+		Properties: runtime.RawExtension{
+			Raw: kmProviderStatus,
+		},
+	}
+	keyManagementProvider := configv1beta1.NamespacedKeyManagementProvider{
+		Status: status,
+	}
+	expectedErr := re.ErrorCodeUnknown.WithDetail("it's a long error from unit test")
+	lastFetchedTime := metav1.Now()
+	updateKMProviderErrorStatusNamespaced(&keyManagementProvider, &expectedErr, &lastFetchedTime)
 
-func (mr *MockRefresher) Refresh(_ context.Context) error {
-	if mr.RefreshError {
-		return errors.New("refresh error")
+	if keyManagementProvider.Status.IsSuccess != false {
+		t.Fatalf("Unexpected error, expected isSuccess to be false , actual %+v", keyManagementProvider.Status.IsSuccess)
+	}
+
+	if keyManagementProvider.Status.Error != expectedErr.Error() {
+		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr, keyManagementProvider.Status.Error)
+	}
+	if keyManagementProvider.Status.BriefError != expectedErr.GetConciseError(150) {
+		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr.GetConciseError(150), keyManagementProvider.Status.Error)
+	}
+
+	//make sure properties of last cached cert was not overridden
+	if len(keyManagementProvider.Status.Properties.Raw) == 0 {
+		t.Fatalf("Unexpected properties,  expected %+v, got %+v", parametersString, string(keyManagementProvider.Status.Properties.Raw))
 	}
-	return nil
 }
 
-func (mr *MockRefresher) GetResult() interface{} {
-	return ctrl.Result{}
+func TestKMProviderUpdateSuccessStatusNamespaced(t *testing.T) {
+	kmProviderStatus := keymanagementprovider.KeyManagementProviderStatus{}
+	properties := map[string]string{}
+	properties["Name"] = "wabbit"
+	properties["Version"] = "ABC"
+
+	kmProviderStatus["Certificates"] = properties
+
+	lastFetchedTime := metav1.Now()
+
+	status := configv1beta1.NamespacedKeyManagementProviderStatus{
+		IsSuccess: false,
+		Error:     "error from last operation",
+	}
+	keyManagementProvider := configv1beta1.NamespacedKeyManagementProvider{
+		Status: status,
+	}
+
+	updateKMProviderSuccessStatusNamespaced(&keyManagementProvider, &lastFetchedTime, kmProviderStatus)
+
+	if keyManagementProvider.Status.IsSuccess != true {
+		t.Fatalf("Expected isSuccess to be true , actual %+v", keyManagementProvider.Status.IsSuccess)
+	}
+
+	if keyManagementProvider.Status.Error != "" {
+		t.Fatalf("Unexpected error string, actual %+v", keyManagementProvider.Status.Error)
+	}
+
+	//make sure properties of last cached cert was updated
+	if len(keyManagementProvider.Status.Properties.Raw) == 0 {
+		t.Fatalf("Properties should not be empty")
+	}
 }
 
-func (mr *MockRefresher) Create(config map[string]interface{}) (refresh.Refresher, error) {
-	createConfigError := config["shouldError"].(bool)
-	refreshError := config["refreshError"].(bool)
-	if createConfigError {
-		return nil, errors.New("create error")
+func TestKMProviderUpdateSuccessStatusNamespaced_emptyProperties(t *testing.T) {
+	lastFetchedTime := metav1.Now()
+	status := configv1beta1.NamespacedKeyManagementProviderStatus{
+		IsSuccess: false,
+		Error:     "error from last operation",
+	}
+	keyManagementProvider := configv1beta1.NamespacedKeyManagementProvider{
+		Status: status,
+	}
+
+	updateKMProviderSuccessStatusNamespaced(&keyManagementProvider, &lastFetchedTime, nil)
+
+	if keyManagementProvider.Status.IsSuccess != true {
+		t.Fatalf("Expected isSuccess to be true , actual %+v", keyManagementProvider.Status.IsSuccess)
+	}
+
+	if keyManagementProvider.Status.Error != "" {
+		t.Fatalf("Unexpected error string, actual %+v", keyManagementProvider.Status.Error)
+	}
+
+	//make sure properties of last cached cert was updated
+	if len(keyManagementProvider.Status.Properties.Raw) != 0 {
+		t.Fatalf("Properties should be empty")
 	}
-	return &MockRefresher{
-		CreateConfigError: createConfigError,
-		RefreshError:      refreshError,
-	}, nil
 }
 
-func init() {
-	refresh.Register("mockRefresher", &MockRefresher{})
+func TestWriteKMProviderStatusNamespaced(t *testing.T) {
+	logger := logrus.WithContext(context.Background())
+	lastFetchedTime := metav1.Now()
+	testCases := []struct {
+		name              string
+		isSuccess         bool
+		kmProvider        *configv1beta1.NamespacedKeyManagementProvider
+		errString         string
+		expectedErrString string
+		reconciler        client.StatusClient
+	}{
+		{
+			name:       "success status",
+			isSuccess:  true,
+			errString:  "",
+			kmProvider: &configv1beta1.NamespacedKeyManagementProvider{},
+			reconciler: &test.MockStatusClient{},
+		},
+		{
+			name:              "error status",
+			isSuccess:         false,
+			kmProvider:        &configv1beta1.NamespacedKeyManagementProvider{},
+			errString:         "a long error string that exceeds the max length of 30 characters",
+			expectedErrString: "UNKNOWN: a long error string that exceeds the max length of 30 characters",
+			reconciler:        &test.MockStatusClient{},
+		},
+		{
+			name:       "status update failed",
+			isSuccess:  true,
+			kmProvider: &configv1beta1.NamespacedKeyManagementProvider{},
+			reconciler: &test.MockStatusClient{
+				UpdateFailed: true,
+			},
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writeKMProviderStatusNamespaced(context.Background(), tc.reconciler, tc.kmProvider, logger, tc.isSuccess, &err, lastFetchedTime, nil)
+
+			if tc.kmProvider.Status.IsSuccess != tc.isSuccess {
+				t.Fatalf("Expected isSuccess to be %+v , actual %+v", tc.isSuccess, tc.kmProvider.Status.IsSuccess)
+			}
+
+			if tc.kmProvider.Status.Error != tc.expectedErrString {
+				t.Fatalf("Expected Error to be %+v , actual %+v", tc.expectedErrString, tc.kmProvider.Status.Error)
+			}
+		})
+	}
 }
diff --git a/pkg/keymanagementprovider/refresh/factory_test.go b/pkg/keymanagementprovider/refresh/factory_test.go
index a4a267c..e8762a4 100644
--- a/pkg/keymanagementprovider/refresh/factory_test.go
+++ b/pkg/keymanagementprovider/refresh/factory_test.go
@@ -22,7 +22,7 @@ import (
 
 type MockRefresher struct{}
 
-func (f *MockRefresher) Create(_ map[string]interface{}) (Refresher, error) {
+func (f *MockRefresher) Create(_ RefresherConfig) (Refresher, error) {
 	return &MockRefresher{}, nil
 }
 
@@ -34,10 +34,14 @@ func (f *MockRefresher) GetResult() interface{} {
 	return nil
 }
 
+func (f *MockRefresher) GetStatus() interface{} {
+	return nil
+}
+
 func TestRefreshFactory_Create(t *testing.T) {
 	Register("mockRefresher", &MockRefresher{})
-	refresherConfig := map[string]interface{}{
-		"type": "mockRefresher",
+	refresherConfig := RefresherConfig{
+		RefresherType: "mockRefresher",
 	}
 	factory := refresherFactories["mockRefresher"]
 	refresher, err := factory.Create(refresherConfig)
@@ -104,8 +108,8 @@ func TestCreateRefresherFromConfig(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			refresherConfig := map[string]interface{}{
-				"type": tt.refresherType,
+			refresherConfig := RefresherConfig{
+				RefresherType: tt.refresherType,
 			}
 			_, err := CreateRefresherFromConfig(refresherConfig)
 			if tt.expectedError && err == nil {
diff --git a/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced_test.go b/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced_test.go
deleted file mode 100644
index 944f548..0000000
--- a/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced_test.go
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
-Copyright The Ratify Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-package refresh
-
-import (
-	"context"
-	"reflect"
-	"testing"
-	"time"
-
-	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
-	re "github.com/ratify-project/ratify/errors"
-	"github.com/ratify-project/ratify/pkg/keymanagementprovider"
-	"github.com/ratify-project/ratify/pkg/keymanagementprovider/mocks"
-	test "github.com/ratify-project/ratify/pkg/utils"
-	"github.com/sirupsen/logrus"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/client/fake"
-)
-
-func TestKubeRefresherNamespaced_Refresh(t *testing.T) {
-	tests := []struct {
-		name           string
-		provider       *configv1beta1.NamespacedKeyManagementProvider
-		request        ctrl.Request
-		mockClient     bool
-		expectedResult ctrl.Result
-		expectedError  bool
-	}{
-		{
-			name: "Non-refreshable",
-			provider: &configv1beta1.NamespacedKeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.NamespacedKeyManagementProviderSpec{
-					Type: "inline",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
-					},
-				},
-			},
-			request: ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-			},
-			expectedResult: ctrl.Result{},
-			expectedError:  false,
-		},
-		{
-			name: "Disabled",
-			provider: &configv1beta1.NamespacedKeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.NamespacedKeyManagementProviderSpec{
-					Type:            "test-kmp",
-					RefreshInterval: "",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
-					},
-				},
-			},
-			request: ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-			},
-			expectedResult: ctrl.Result{},
-			expectedError:  false,
-		},
-		{
-			name: "Refreshable",
-			provider: &configv1beta1.NamespacedKeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.NamespacedKeyManagementProviderSpec{
-					Type:            "test-kmp",
-					RefreshInterval: "1m",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
-					},
-				},
-			},
-			request: ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-			},
-			expectedResult: ctrl.Result{RequeueAfter: time.Minute},
-			expectedError:  false,
-		},
-		{
-			name: "Invalid Interval",
-			provider: &configv1beta1.NamespacedKeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.NamespacedKeyManagementProviderSpec{
-					Type:            "",
-					RefreshInterval: "1mm",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
-					},
-				},
-			},
-			request: ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-			},
-			expectedResult: ctrl.Result{},
-			expectedError:  true,
-		},
-		{
-			name: "IsNotFound",
-			provider: &configv1beta1.NamespacedKeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.NamespacedKeyManagementProviderSpec{
-					Type:            "",
-					RefreshInterval: "",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
-					},
-				},
-			},
-			expectedResult: ctrl.Result{},
-			expectedError:  false,
-		},
-		{
-			name:          "UnableToFetchKMP",
-			mockClient:    true,
-			expectedError: true,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			var client client.Client
-
-			if tt.mockClient {
-				client = mocks.TestClient{}
-			} else {
-				scheme, _ := test.CreateScheme()
-				client = fake.NewClientBuilder().WithScheme(scheme).WithObjects(tt.provider).Build()
-			}
-
-			kr := &KubeRefresherNamespaced{
-				Client:  client,
-				Request: tt.request,
-			}
-			err := kr.Refresh(context.Background())
-			result := kr.GetResult()
-			if !reflect.DeepEqual(result, tt.expectedResult) {
-				t.Fatalf("Expected nil but got %v with error %v", result, err)
-			}
-			if tt.expectedError && err == nil {
-				t.Fatalf("Expected error but got nil")
-			}
-		})
-	}
-}
-
-func TestKubeRefresherNamespaced_Create(t *testing.T) {
-	tests := []struct {
-		name          string
-		config        map[string]interface{}
-		expectedError bool
-	}{
-		{
-			name: "Success",
-			config: map[string]interface{}{
-				"client":  &mocks.TestClient{},
-				"request": ctrl.Request{},
-			},
-			expectedError: false,
-		},
-		{
-			name: "ClientMissing",
-			config: map[string]interface{}{
-				"request": ctrl.Request{},
-			},
-			expectedError: true,
-		},
-		{
-			name: "RequestMissing",
-			config: map[string]interface{}{
-				"client": &mocks.TestClient{},
-			},
-			expectedError: true,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			kr := &KubeRefresherNamespaced{}
-			_, err := kr.Create(tt.config)
-			if tt.expectedError && err == nil {
-				t.Fatalf("Expected error but got nil")
-			}
-		})
-	}
-}
-
-func TestKMProviderUpdateErrorStatusNamespaced(t *testing.T) {
-	var parametersString = "{\"certs\":{\"name\":\"certName\"}}"
-	var kmProviderStatus = []byte(parametersString)
-
-	status := configv1beta1.NamespacedKeyManagementProviderStatus{
-		IsSuccess: true,
-		Properties: runtime.RawExtension{
-			Raw: kmProviderStatus,
-		},
-	}
-	keyManagementProvider := configv1beta1.NamespacedKeyManagementProvider{
-		Status: status,
-	}
-	expectedErr := re.ErrorCodeUnknown.WithDetail("it's a long error from unit test")
-	lastFetchedTime := metav1.Now()
-	updateKMProviderErrorStatusNamespaced(&keyManagementProvider, &expectedErr, &lastFetchedTime)
-
-	if keyManagementProvider.Status.IsSuccess != false {
-		t.Fatalf("Unexpected error, expected isSuccess to be false , actual %+v", keyManagementProvider.Status.IsSuccess)
-	}
-
-	if keyManagementProvider.Status.Error != expectedErr.Error() {
-		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr, keyManagementProvider.Status.Error)
-	}
-	if keyManagementProvider.Status.BriefError != expectedErr.GetConciseError(150) {
-		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr.GetConciseError(150), keyManagementProvider.Status.Error)
-	}
-
-	//make sure properties of last cached cert was not overridden
-	if len(keyManagementProvider.Status.Properties.Raw) == 0 {
-		t.Fatalf("Unexpected properties,  expected %+v, got %+v", parametersString, string(keyManagementProvider.Status.Properties.Raw))
-	}
-}
-
-func TestKMProviderUpdateSuccessStatusNamespaced(t *testing.T) {
-	kmProviderStatus := keymanagementprovider.KeyManagementProviderStatus{}
-	properties := map[string]string{}
-	properties["Name"] = "wabbit"
-	properties["Version"] = "ABC"
-
-	kmProviderStatus["Certificates"] = properties
-
-	lastFetchedTime := metav1.Now()
-
-	status := configv1beta1.NamespacedKeyManagementProviderStatus{
-		IsSuccess: false,
-		Error:     "error from last operation",
-	}
-	keyManagementProvider := configv1beta1.NamespacedKeyManagementProvider{
-		Status: status,
-	}
-
-	updateKMProviderSuccessStatusNamespaced(&keyManagementProvider, &lastFetchedTime, kmProviderStatus)
-
-	if keyManagementProvider.Status.IsSuccess != true {
-		t.Fatalf("Expected isSuccess to be true , actual %+v", keyManagementProvider.Status.IsSuccess)
-	}
-
-	if keyManagementProvider.Status.Error != "" {
-		t.Fatalf("Unexpected error string, actual %+v", keyManagementProvider.Status.Error)
-	}
-
-	//make sure properties of last cached cert was updated
-	if len(keyManagementProvider.Status.Properties.Raw) == 0 {
-		t.Fatalf("Properties should not be empty")
-	}
-}
-
-func TestKMProviderUpdateSuccessStatusNamespaced_emptyProperties(t *testing.T) {
-	lastFetchedTime := metav1.Now()
-	status := configv1beta1.NamespacedKeyManagementProviderStatus{
-		IsSuccess: false,
-		Error:     "error from last operation",
-	}
-	keyManagementProvider := configv1beta1.NamespacedKeyManagementProvider{
-		Status: status,
-	}
-
-	updateKMProviderSuccessStatusNamespaced(&keyManagementProvider, &lastFetchedTime, nil)
-
-	if keyManagementProvider.Status.IsSuccess != true {
-		t.Fatalf("Expected isSuccess to be true , actual %+v", keyManagementProvider.Status.IsSuccess)
-	}
-
-	if keyManagementProvider.Status.Error != "" {
-		t.Fatalf("Unexpected error string, actual %+v", keyManagementProvider.Status.Error)
-	}
-
-	//make sure properties of last cached cert was updated
-	if len(keyManagementProvider.Status.Properties.Raw) != 0 {
-		t.Fatalf("Properties should be empty")
-	}
-}
-
-func TestWriteKMProviderStatusNamespaced(t *testing.T) {
-	logger := logrus.WithContext(context.Background())
-	lastFetchedTime := metav1.Now()
-	testCases := []struct {
-		name              string
-		isSuccess         bool
-		kmProvider        *configv1beta1.NamespacedKeyManagementProvider
-		errString         string
-		expectedErrString string
-		reconciler        client.StatusClient
-	}{
-		{
-			name:       "success status",
-			isSuccess:  true,
-			errString:  "",
-			kmProvider: &configv1beta1.NamespacedKeyManagementProvider{},
-			reconciler: &test.MockStatusClient{},
-		},
-		{
-			name:              "error status",
-			isSuccess:         false,
-			kmProvider:        &configv1beta1.NamespacedKeyManagementProvider{},
-			errString:         "a long error string that exceeds the max length of 30 characters",
-			expectedErrString: "UNKNOWN: a long error string that exceeds the max length of 30 characters",
-			reconciler:        &test.MockStatusClient{},
-		},
-		{
-			name:       "status update failed",
-			isSuccess:  true,
-			kmProvider: &configv1beta1.NamespacedKeyManagementProvider{},
-			reconciler: &test.MockStatusClient{
-				UpdateFailed: true,
-			},
-		},
-	}
-
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
-			writeKMProviderStatusNamespaced(context.Background(), tc.reconciler, tc.kmProvider, logger, tc.isSuccess, &err, lastFetchedTime, nil)
-
-			if tc.kmProvider.Status.IsSuccess != tc.isSuccess {
-				t.Fatalf("Expected isSuccess to be %+v , actual %+v", tc.isSuccess, tc.kmProvider.Status.IsSuccess)
-			}
-
-			if tc.kmProvider.Status.Error != tc.expectedErrString {
-				t.Fatalf("Expected Error to be %+v , actual %+v", tc.expectedErrString, tc.kmProvider.Status.Error)
-			}
-		})
-	}
-}
diff --git a/pkg/keymanagementprovider/refresh/kubeRefresh_test.go b/pkg/keymanagementprovider/refresh/kubeRefresh_test.go
index 29319ab..9875098 100644
--- a/pkg/keymanagementprovider/refresh/kubeRefresh_test.go
+++ b/pkg/keymanagementprovider/refresh/kubeRefresh_test.go
@@ -18,168 +18,120 @@ package refresh
 
 import (
 	"context"
+	"crypto"
+	"crypto/x509"
+	"errors"
 	"reflect"
 	"testing"
 	"time"
 
-	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
-	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider"
+	"github.com/ratify-project/ratify/pkg/keymanagementprovider/config"
 	_ "github.com/ratify-project/ratify/pkg/keymanagementprovider/inline"
-	"github.com/ratify-project/ratify/pkg/keymanagementprovider/mocks"
-	test "github.com/ratify-project/ratify/pkg/utils"
-	"github.com/sirupsen/logrus"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
+	mock "github.com/ratify-project/ratify/pkg/keymanagementprovider/mocks"
 	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 )
 
 func TestKubeRefresher_Refresh(t *testing.T) {
 	tests := []struct {
-		name           string
-		provider       *configv1beta1.KeyManagementProvider
-		request        ctrl.Request
-		mockClient     bool
-		expectedResult ctrl.Result
-		expectedError  bool
+		name                    string
+		providerRawParameters   []byte
+		providerType            string
+		providerRefreshInterval string
+		GetCertsFunc            func(_ context.Context) (map[keymanagementprovider.KMPMapKey][]*x509.Certificate, keymanagementprovider.KeyManagementProviderStatus, error)
+		GetKeysFunc             func(_ context.Context) (map[keymanagementprovider.KMPMapKey]crypto.PublicKey, keymanagementprovider.KeyManagementProviderStatus, error)
+		IsRefreshableFunc       func() bool
+		expectedResult          ctrl.Result
+		expectedError           bool
 	}{
 		{
-			name: "Non-refreshable",
-			provider: &configv1beta1.KeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.KeyManagementProviderSpec{
-					Type: "inline",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"type": "inline", "contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
-					},
-				},
-			},
-			request: ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-			},
-			expectedResult: ctrl.Result{},
-			expectedError:  false,
+			name:                  "Non-refreshable",
+			providerRawParameters: []byte(`{"contentType": "certificate", "value": "-----BEGIN CERTIFICATE-----\nMIID2jCCAsKgAwIBAgIQXy2VqtlhSkiZKAGhsnkjbDANBgkqhkiG9w0BAQsFADBvMRswGQYDVQQD\nExJyYXRpZnkuZXhhbXBsZS5jb20xDzANBgNVBAsTBk15IE9yZzETMBEGA1UEChMKTXkgQ29tcGFu\neTEQMA4GA1UEBxMHUmVkbW9uZDELMAkGA1UECBMCV0ExCzAJBgNVBAYTAlVTMB4XDTIzMDIwMTIy\nNDUwMFoXDTI0MDIwMTIyNTUwMFowbzEbMBkGA1UEAxMScmF0aWZ5LmV4YW1wbGUuY29tMQ8wDQYD\nVQQLEwZNeSBPcmcxEzARBgNVBAoTCk15IENvbXBhbnkxEDAOBgNVBAcTB1JlZG1vbmQxCzAJBgNV\nBAgTAldBMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL10bM81\npPAyuraORABsOGS8M76Bi7Guwa3JlM1g2D8CuzSfSTaaT6apy9GsccxUvXd5cmiP1ffna5z+EFmc\nizFQh2aq9kWKWXDvKFXzpQuhyqD1HeVlRlF+V0AfZPvGt3VwUUjNycoUU44ctCWmcUQP/KShZev3\n6SOsJ9q7KLjxxQLsUc4mg55eZUThu8mGB8jugtjsnLUYvIWfHhyjVpGrGVrdkDMoMn+u33scOmrt\nsBljvq9WVo4T/VrTDuiOYlAJFMUae2Ptvo0go8XTN3OjLblKeiK4C+jMn9Dk33oGIT9pmX0vrDJV\nX56w/2SejC1AxCPchHaMuhlwMpftBGkCAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQC\nMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAU0eaKkZj+MS9jCp9Dg1zdv3v/aKww\nHQYDVR0OBBYEFNHmipGY/jEvYwqfQ4Nc3b97/2isMA0GCSqGSIb3DQEBCwUAA4IBAQBNDcmSBizF\nmpJlD8EgNcUCy5tz7W3+AAhEbA3vsHP4D/UyV3UgcESx+L+Nye5uDYtTVm3lQejs3erN2BjW+ds+\nXFnpU/pVimd0aYv6mJfOieRILBF4XFomjhrJOLI55oVwLN/AgX6kuC3CJY2NMyJKlTao9oZgpHhs\nLlxB/r0n9JnUoN0Gq93oc1+OLFjPI7gNuPXYOP1N46oKgEmAEmNkP1etFrEjFRgsdIFHksrmlOlD\nIed9RcQ087VLjmuymLgqMTFX34Q3j7XgN2ENwBSnkHotE9CcuGRW+NuiOeJalL8DBmFXXWwHTKLQ\nPp5g6m1yZXylLJaFLKz7tdMmO355\n-----END CERTIFICATE-----\n"}`),
+			providerType:          "inline",
+			IsRefreshableFunc:     func() bool { return false },
+			expectedResult:        ctrl.Result{},
+			expectedError:         false,
 		},
 		{
-			name: "Disabled",
-			provider: &configv1beta1.KeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.KeyManagementProviderSpec{
-					Type:            "test-kmp",
-					RefreshInterval: "",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
-					},
-				},
-			},
-			request: ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-			},
-			expectedResult: ctrl.Result{},
-			expectedError:  false,
+			name:                    "Disabled",
+			providerRawParameters:   []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
+			providerType:            "test-kmp",
+			providerRefreshInterval: "",
+			IsRefreshableFunc:       func() bool { return true },
+			expectedResult:          ctrl.Result{},
+			expectedError:           false,
 		},
 		{
-			name: "Refreshable",
-			provider: &configv1beta1.KeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.KeyManagementProviderSpec{
-					Type:            "test-kmp",
-					RefreshInterval: "1m",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
-					},
-				},
-			},
-			request: ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-			},
-			expectedResult: ctrl.Result{RequeueAfter: time.Minute},
-			expectedError:  false,
+			name:                    "Refreshable",
+			providerRawParameters:   []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
+			providerType:            "test-kmp",
+			providerRefreshInterval: "1m",
+			IsRefreshableFunc:       func() bool { return true },
+			expectedResult:          ctrl.Result{RequeueAfter: time.Minute},
+			expectedError:           false,
 		},
 		{
-			name: "Invalid Interval",
-			provider: &configv1beta1.KeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.KeyManagementProviderSpec{
-					Type:            "",
-					RefreshInterval: "1mm",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
-					},
-				},
-			},
-			request: ctrl.Request{
-				NamespacedName: client.ObjectKey{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-			},
-			expectedResult: ctrl.Result{},
-			expectedError:  true,
+			name:                    "Invalid Interval",
+			providerRawParameters:   []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
+			providerType:            "test-kmp",
+			providerRefreshInterval: "1mm",
+			IsRefreshableFunc:       func() bool { return true },
+			expectedResult:          ctrl.Result{},
+			expectedError:           true,
 		},
 		{
-			name: "IsNotFound",
-			provider: &configv1beta1.KeyManagementProvider{
-				ObjectMeta: metav1.ObjectMeta{
-					Namespace: "",
-					Name:      "kmpName",
-				},
-				Spec: configv1beta1.KeyManagementProviderSpec{
-					Type:            "",
-					RefreshInterval: "",
-					Parameters: runtime.RawExtension{
-						Raw: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
-					},
-				},
+			name: "Error Fetching Certificates",
+			GetCertsFunc: func(_ context.Context) (map[keymanagementprovider.KMPMapKey][]*x509.Certificate, keymanagementprovider.KeyManagementProviderStatus, error) {
+				// Example behavior: Return an error
+				return nil, nil, errors.New("test error")
 			},
-			expectedResult: ctrl.Result{},
-			expectedError:  false,
+			providerRawParameters: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
+			providerType:          "test-kmp-error",
+			IsRefreshableFunc:     func() bool { return true },
+			expectedError:         true,
 		},
 		{
-			name:          "UnableToFetchKMP",
-			mockClient:    true,
-			expectedError: true,
+			name: "Error Fetching Keys",
+			GetKeysFunc: func(_ context.Context) (map[keymanagementprovider.KMPMapKey]crypto.PublicKey, keymanagementprovider.KeyManagementProviderStatus, error) {
+				// Example behavior: Return an error
+				return nil, nil, errors.New("test error")
+			},
+			providerRawParameters: []byte(`{"vaultURI": "https://yourkeyvault.vault.azure.net/", "certificates": [{"name": "cert1", "version": "1"}], "tenantID": "yourtenantID", "clientID": "yourclientID"}`),
+			providerType:          "test-kmp-error",
+			IsRefreshableFunc:     func() bool { return true },
+			expectedError:         true,
 		},
 	}
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			var client client.Client
-
-			if tt.mockClient {
-				client = mocks.TestClient{}
+			var factory mock.TestKeyManagementProviderFactory
+
+			if tt.GetCertsFunc != nil {
+				factory = mock.TestKeyManagementProviderFactory{
+					GetCertsFunc:      tt.GetCertsFunc,
+					IsRefreshableFunc: tt.IsRefreshableFunc,
+				}
+			} else if tt.GetKeysFunc != nil {
+				factory = mock.TestKeyManagementProviderFactory{
+					GetKeysFunc:       tt.GetKeysFunc,
+					IsRefreshableFunc: tt.IsRefreshableFunc,
+				}
 			} else {
-				scheme, _ := test.CreateScheme()
-				client = fake.NewClientBuilder().WithScheme(scheme).WithObjects(tt.provider).Build()
+				factory = mock.TestKeyManagementProviderFactory{
+					IsRefreshableFunc: tt.IsRefreshableFunc,
+				}
 			}
 
+			provider, _ := factory.Create("", config.KeyManagementProviderConfig{}, "")
+
 			kr := &KubeRefresher{
-				Client:  client,
-				Request: tt.request,
+				Provider:                provider,
+				ProviderType:            tt.providerType,
+				ProviderRefreshInterval: tt.providerRefreshInterval,
+				Resource:                "kmpname",
 			}
+
 			err := kr.Refresh(context.Background())
 			result := kr.GetResult()
 			if !reflect.DeepEqual(result, tt.expectedResult) {
@@ -192,190 +144,93 @@ func TestKubeRefresher_Refresh(t *testing.T) {
 	}
 }
 
-func TestKubeRefresher_Create(t *testing.T) {
-	tests := []struct {
-		name          string
-		config        map[string]interface{}
-		expectedError bool
-	}{
-		{
-			name: "Success",
-			config: map[string]interface{}{
-				"client":  &mocks.TestClient{},
-				"request": ctrl.Request{},
-			},
-			expectedError: false,
-		},
-		{
-			name: "ClientMissing",
-			config: map[string]interface{}{
-				"request": ctrl.Request{},
-			},
-			expectedError: true,
-		},
-		{
-			name: "RequestMissing",
-			config: map[string]interface{}{
-				"client": &mocks.TestClient{},
-			},
-			expectedError: true,
-		},
+func TestKubeRefresher_GetResult(t *testing.T) {
+	kr := &KubeRefresher{
+		Result: ctrl.Result{RequeueAfter: time.Minute},
 	}
 
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			kr := &KubeRefresher{}
-			_, err := kr.Create(tt.config)
-			if tt.expectedError && err == nil {
-				t.Fatalf("Expected error but got nil")
-			}
-		})
-	}
-}
+	result := kr.GetResult()
+	expectedResult := ctrl.Result{RequeueAfter: time.Minute}
 
-func TestKMProviderUpdateErrorStatus(t *testing.T) {
-	var parametersString = "{\"certs\":{\"name\":\"certName\"}}"
-	var kmProviderStatus = []byte(parametersString)
-
-	status := configv1beta1.KeyManagementProviderStatus{
-		IsSuccess: true,
-		Properties: runtime.RawExtension{
-			Raw: kmProviderStatus,
-		},
-	}
-	keyManagementProvider := configv1beta1.KeyManagementProvider{
-		Status: status,
-	}
-	expectedErr := re.ErrorCodeUnknown.WithDetail("it's a long error from unit test")
-	lastFetchedTime := metav1.Now()
-	updateKMProviderErrorStatus(&keyManagementProvider, &expectedErr, &lastFetchedTime)
-
-	if keyManagementProvider.Status.IsSuccess != false {
-		t.Fatalf("Unexpected error, expected isSuccess to be false , actual %+v", keyManagementProvider.Status.IsSuccess)
-	}
-
-	if keyManagementProvider.Status.Error != expectedErr.Error() {
-		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr, keyManagementProvider.Status.Error)
-	}
-	if keyManagementProvider.Status.BriefError != expectedErr.GetConciseError(150) {
-		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr.GetConciseError(150), keyManagementProvider.Status.Error)
-	}
-
-	//make sure properties of last cached cert was not overridden
-	if len(keyManagementProvider.Status.Properties.Raw) == 0 {
-		t.Fatalf("Unexpected properties,  expected %+v, got %+v", parametersString, string(keyManagementProvider.Status.Properties.Raw))
+	if !reflect.DeepEqual(result, expectedResult) {
+		t.Fatalf("Expected result %v, but got %v", expectedResult, result)
 	}
 }
-
-// TestKMProviderUpdateSuccessStatus tests the updateSuccessStatus method
-func TestKMProviderUpdateSuccessStatus(t *testing.T) {
-	kmProviderStatus := keymanagementprovider.KeyManagementProviderStatus{}
-	properties := map[string]string{}
-	properties["Name"] = "wabbit"
-	properties["Version"] = "ABC"
-
-	kmProviderStatus["Certificates"] = properties
-
-	lastFetchedTime := metav1.Now()
-
-	status := configv1beta1.KeyManagementProviderStatus{
-		IsSuccess: false,
-		Error:     "error from last operation",
-	}
-	keyManagementProvider := configv1beta1.KeyManagementProvider{
-		Status: status,
-	}
-
-	updateKMProviderSuccessStatus(&keyManagementProvider, &lastFetchedTime, kmProviderStatus)
-
-	if keyManagementProvider.Status.IsSuccess != true {
-		t.Fatalf("Expected isSuccess to be true , actual %+v", keyManagementProvider.Status.IsSuccess)
-	}
-
-	if keyManagementProvider.Status.Error != "" {
-		t.Fatalf("Unexpected error string, actual %+v", keyManagementProvider.Status.Error)
-	}
-
-	//make sure properties of last cached cert was updated
-	if len(keyManagementProvider.Status.Properties.Raw) == 0 {
-		t.Fatalf("Properties should not be empty")
-	}
-}
-
-// TestKMProviderUpdateSuccessStatus tests the updateSuccessStatus method with empty properties
-func TestKMProviderUpdateSuccessStatus_emptyProperties(t *testing.T) {
-	lastFetchedTime := metav1.Now()
-	status := configv1beta1.KeyManagementProviderStatus{
-		IsSuccess: false,
-		Error:     "error from last operation",
-	}
-	keyManagementProvider := configv1beta1.KeyManagementProvider{
-		Status: status,
-	}
-
-	updateKMProviderSuccessStatus(&keyManagementProvider, &lastFetchedTime, nil)
-
-	if keyManagementProvider.Status.IsSuccess != true {
-		t.Fatalf("Expected isSuccess to be true , actual %+v", keyManagementProvider.Status.IsSuccess)
+func TestKubeRefresher_GetStatus(t *testing.T) {
+	kr := &KubeRefresher{
+		Status: keymanagementprovider.KeyManagementProviderStatus{
+			"attribute1": "value1",
+			"attribute2": "value2",
+		},
 	}
 
-	if keyManagementProvider.Status.Error != "" {
-		t.Fatalf("Unexpected error string, actual %+v", keyManagementProvider.Status.Error)
+	status := kr.GetStatus()
+	expectedStatus := keymanagementprovider.KeyManagementProviderStatus{
+		"attribute1": "value1",
+		"attribute2": "value2",
 	}
 
-	//make sure properties of last cached cert was updated
-	if len(keyManagementProvider.Status.Properties.Raw) != 0 {
-		t.Fatalf("Properties should be empty")
+	if !reflect.DeepEqual(status, expectedStatus) {
+		t.Fatalf("Expected status %v, but got %v", expectedStatus, status)
 	}
 }
-
-func TestWriteKMProviderStatus(t *testing.T) {
-	logger := logrus.WithContext(context.Background())
-	lastFetchedTime := metav1.Now()
-	testCases := []struct {
-		name              string
-		isSuccess         bool
-		kmProvider        *configv1beta1.KeyManagementProvider
-		errString         string
-		expectedErrString string
-		reconciler        client.StatusClient
+func TestKubeRefresher_Create(t *testing.T) {
+	tests := []struct {
+		name                    string
+		config                  RefresherConfig
+		expectedProviderType    string
+		expectedRefreshInterval string
+		expectedResource        string
 	}{
 		{
-			name:       "success status",
-			isSuccess:  true,
-			errString:  "",
-			kmProvider: &configv1beta1.KeyManagementProvider{},
-			reconciler: &test.MockStatusClient{},
-		},
-		{
-			name:              "error status",
-			isSuccess:         false,
-			kmProvider:        &configv1beta1.KeyManagementProvider{},
-			errString:         "a long error string that exceeds the max length of 150 characters",
-			expectedErrString: "UNKNOWN: a long error string that exceeds the max length of 150 characters",
-			reconciler:        &test.MockStatusClient{},
+			name: "Valid Config",
+			config: RefresherConfig{
+				Provider:                &mock.TestKeyManagementProvider{},
+				ProviderType:            "test-kmp",
+				ProviderRefreshInterval: "1m",
+				Resource:                "test-resource",
+			},
+			expectedProviderType:    "test-kmp",
+			expectedRefreshInterval: "1m",
+			expectedResource:        "test-resource",
 		},
 		{
-			name:       "status update failed",
-			isSuccess:  true,
-			kmProvider: &configv1beta1.KeyManagementProvider{},
-			reconciler: &test.MockStatusClient{
-				UpdateFailed: true,
+			name: "Empty Config",
+			config: RefresherConfig{
+				Provider:                nil,
+				ProviderType:            "",
+				ProviderRefreshInterval: "",
+				Resource:                "",
 			},
+			expectedProviderType:    "",
+			expectedRefreshInterval: "",
+			expectedResource:        "",
 		},
 	}
 
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
-			writeKMProviderStatus(context.Background(), tc.reconciler, tc.kmProvider, logger, tc.isSuccess, &err, lastFetchedTime, nil)
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			kr := &KubeRefresher{}
+			refresher, err := kr.Create(tt.config)
+			if err != nil {
+				t.Fatalf("Expected no error, but got %v", err)
+			}
+
+			kubeRefresher, ok := refresher.(*KubeRefresher)
+			if !ok {
+				t.Fatalf("Expected KubeRefresher type, but got %T", refresher)
+			}
+
+			if kubeRefresher.ProviderType != tt.expectedProviderType {
+				t.Fatalf("Expected ProviderType %v, but got %v", tt.expectedProviderType, kubeRefresher.ProviderType)
+			}
 
-			if tc.kmProvider.Status.IsSuccess != tc.isSuccess {
-				t.Fatalf("Expected isSuccess to be: %+v, actual: %+v", tc.isSuccess, tc.kmProvider.Status.IsSuccess)
+			if kubeRefresher.ProviderRefreshInterval != tt.expectedRefreshInterval {
+				t.Fatalf("Expected ProviderRefreshInterval %v, but got %v", tt.expectedRefreshInterval, kubeRefresher.ProviderRefreshInterval)
 			}
 
-			if tc.kmProvider.Status.Error != tc.expectedErrString {
-				t.Fatalf("Expected Error to be: %+v, actual: %+v", tc.expectedErrString, tc.kmProvider.Status.Error)
+			if kubeRefresher.Resource != tt.expectedResource {
+				t.Fatalf("Expected Resource %v, but got %v", tt.expectedResource, kubeRefresher.Resource)
 			}
 		})
 	}