Repository: deislabs/ratify (go)

Issue:
same certificateStore name in different namespace
### What happened in your environment?

crd certificateStore is namespaced resource, which means it could exist multiple certificateStore with the same name. However, in verifier crd, the `verificationCertStores/certs` does not support to input namespace.

My repro:
1. `curl -L https://raw.githubusercontent.com/deislabs/ratify/main/helmfile.yaml | helmfile sync -f - `
2. duplicate the inline certificate store from gatekeeper-system namespace to default namespace
3. modify the certificate store under gatekeeper-system to an incorrect cert
4. run `kubectl run demo --image=ghcr.io/deislabs/ratify/notary-image:signed` it will reports failed. error: `signature is not produced by a trusted signer`
5. delete the certificate store under gatekeeper-system, rerun the pod creation, it will still failed. report error: `error while loading the trust store, unable to fetch certificates for namedStore: certs`
6.  Restart ratify pod, the cerification will succeeded


### What did you expect to happen?

_No response_

### What version of Kubernetes are you running?

1.26.4

### What version of Ratify are you running?

v1.0.0-rc.7

### Anything else you would like to add?

_No response_

### Are you willing to submit PRs to contribute to this bug fix?

- [ ] Yes, I am willing to implement it.

Pull request description:
fix: set default certstore namespace in notation verifier to uniquely identify certificate store resource
# Description
Fixes #1061

## What this PR does / why we need it:

currently certStore defined in trust policy only contains name which means the CertStore cannot be uniquely identified. To address , the PR introduces below changes:

- Updated certstore controller to cache certificates based on key "namepsace/name". E.g. gatekeeper-system/ratify-notation-inline-cert
- updated verifier reconcile to append namespace to cert store (if certSTore is not name spaced already). The default namespace would be the verifier's namespace, given verifier are cluster scoped resource, use ratify deployed namespace
as a fall back.
- remove verificateCertStore from configMap we cannot infer namespace from configmap. Verifier/Store are overridden by CRD at runtime, Ratify team is working on cleaning configMap to avoid user confusion. Issue  #1104 https://github.com/deislabs/ratify/issues/1104
- moved RatifyNamespace env variable into util so it can be used by both auth provider and crd controllers
- add unit test and e2e test for cert store references across namespace

Note: a doc PR will be created in the doc repo
## 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 #1061

## Type of change

Please delete options that are not relevant.

- [ X ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Helm Chart Change (any edit/addition/update that is necessary for changes merged to the `main` branch)
- [X ] This change requires a documentation update

# How Has This Been Tested?
 
- cli scenario covered by cli test
- validated namespace is append they don't exist
- validated if namespace is already provided, they are not overridden
  

Patch:
diff --git a/charts/ratify/README.md b/charts/ratify/README.md
index 6e21e95..99d605d 100644
--- a/charts/ratify/README.md
+++ b/charts/ratify/README.md
@@ -107,7 +107,7 @@ $ helm upgrade -n gatekeeper-system [RELEASE_NAME] ratify/ratify
 | azureWorkloadIdentity.clientId                     | ClientID of AAD application/Managed identity associated with Workload Identity                                                                                                                                                      | ``                             |
 | azureManagedIdentity.clientId                      | ClientID of Managed identity                                                                                                                                                                                                        | ``                             |
 | azureManagedIdentity.tenantId                      | TenantID of Managed Identity resource                                                                                                                                                                                               | ``                             |
-| akvCertConfig.enabled                              | Enables/disables Azure Key Vault certificate store                                                                                                                                                                                  | `false`                        |
+| akvCertConfig.enabled                              | Enables/disables Azure Key Vault certificate store. If you are using a custom chart, certificate store should be referenced through a Verifier CR. References in ConfigMap will not be correctly resolved.                                                                                                                                                                   | `false`                        |
 | akvCertConfig.vaultURI                             | Vault URI for AKV configured                                                                                                                                                                                                        | ``                             |
 | akvCertConfig.cert1Name                            | Exact name of the certificate stored in AKV                                                                                                                                                                                         | ``                             |
 | akvCertConfig.cert1Version                         | Exact version of certificate to use from AKV                                                                                                                                                                                        | ``                             |
diff --git a/charts/ratify/templates/configmap.yaml b/charts/ratify/templates/configmap.yaml
index 67046d7..17a03a7 100644
--- a/charts/ratify/templates/configmap.yaml
+++ b/charts/ratify/templates/configmap.yaml
@@ -72,14 +72,7 @@ data:
             {
                 "name":"notation",
                 "artifactTypes" : "application/vnd.cncf.notary.signature",
-                "verificationCertStores": {
-                  "certs":[
-                    {{- if .Values.akvCertConfig.enabled }}
-                    "certstore-akv"
-                    {{- else }}
-                    "{{ include "ratify.fullname" . }}-notation-inline-cert"
-                    {{- end }}
-                   ]
+                "verificationCertStores": {                 
                 },
                 "trustPolicyDoc": {
                   "version": "1.0",
diff --git a/cmd/ratify/cmd/verify.go b/cmd/ratify/cmd/verify.go
index c89e697..1700141 100644
--- a/cmd/ratify/cmd/verify.go
+++ b/cmd/ratify/cmd/verify.go
@@ -21,6 +21,7 @@ import (
 	"fmt"
 
 	"github.com/deislabs/ratify/config"
+	"github.com/deislabs/ratify/internal/constants"
 	"github.com/deislabs/ratify/internal/logger"
 	e "github.com/deislabs/ratify/pkg/executor"
 	ef "github.com/deislabs/ratify/pkg/executor/core"
@@ -99,7 +100,7 @@ func verify(opts verifyCmdOptions) error {
 		return err
 	}
 
-	verifiers, err := vf.CreateVerifiersFromConfig(cf.VerifiersConfig, config.GetDefaultPluginPath())
+	verifiers, err := vf.CreateVerifiersFromConfig(cf.VerifiersConfig, config.GetDefaultPluginPath(), constants.EmptyNamespace)
 
 	if err != nil {
 		return err
diff --git a/config/config.go b/config/config.go
index f3c9b26..92a31f2 100644
--- a/config/config.go
+++ b/config/config.go
@@ -24,6 +24,7 @@ import (
 	"path/filepath"
 	"sync"
 
+	"github.com/deislabs/ratify/internal/constants"
 	"github.com/deislabs/ratify/internal/logger"
 	exConfig "github.com/deislabs/ratify/pkg/executor/config"
 	"github.com/deislabs/ratify/pkg/homedir"
@@ -91,7 +92,8 @@ func CreateFromConfig(cf Config) ([]referrerstore.ReferrerStore, []verifier.Refe
 	}
 	logrus.Infof("stores successfully created. number of stores %d", len(stores))
 
-	verifiers, err := vf.CreateVerifiersFromConfig(cf.VerifiersConfig, GetDefaultPluginPath())
+	// in K8s , verifiers CR are deployed to specific namespace, namespace is not applicable in config file scenario
+	verifiers, err := vf.CreateVerifiersFromConfig(cf.VerifiersConfig, GetDefaultPluginPath(), constants.EmptyNamespace)
 
 	if err != nil {
 		return nil, nil, nil, errors.Wrap(err, "failed to load verifiers from config")
diff --git a/config/samples/config_v1beta1_verifier_notation_specificnscertstore.yaml b/config/samples/config_v1beta1_verifier_notation_specificnscertstore.yaml
new file mode 100644
index 0000000..4cd4c09
--- /dev/null
+++ b/config/samples/config_v1beta1_verifier_notation_specificnscertstore.yaml
@@ -0,0 +1,23 @@
+apiVersion: config.ratify.deislabs.io/v1beta1
+kind: Verifier
+metadata:
+  name: verifier-notation
+spec:
+  name: notation
+  artifactTypes: application/vnd.cncf.notary.signature
+  parameters:
+     verificationCertStores:
+       certs:
+         - default/ratify-notation-inline-cert
+     trustPolicyDoc:
+      version: "1.0"
+      trustPolicies:
+        - name: default
+          registryScopes:
+            - "*"
+          signatureVerification:
+            level: strict
+          trustStores:
+            - ca:certs
+          trustedIdentities:
+            - "*"
diff --git a/docs/design/Azure Kubernetes Workload Identity AuthProvider.md b/docs/design/Azure Kubernetes Workload Identity AuthProvider.md
index 18d454e..90836b0 100644
--- a/docs/design/Azure Kubernetes Workload Identity AuthProvider.md
+++ b/docs/design/Azure Kubernetes Workload Identity AuthProvider.md
@@ -81,7 +81,7 @@ EOF
 
 ## AzureWIAuthProvider Implementation
 ```
-// AzureK8Conf describes the configuration of Azure K8 Auth Provider
+// AzureK8Conf describes the configuration of Azure K8s Auth Provider
 type AzureWIConf struct {
     Name           string     `json:"name"`
 }
diff --git a/docs/design/K8s Secrets AuthProvider.md b/docs/design/K8s Secrets AuthProvider.md
index e5d7d6b..1ba9f65 100644
--- a/docs/design/K8s Secrets AuthProvider.md
+++ b/docs/design/K8s Secrets AuthProvider.md
@@ -1,7 +1,7 @@
 # K8s Secrets AuthProvider
 Author: Akash Singhal (@akashsinghal)
 
-Goal: Create a Kubernetes Secret Authentication Provider which will use K8 secrets to resolve registry credentials for an artifact. In the `auth-provider` section of the ORAS plugin configuration, the `k8s-secrets` auth-provider contains a list of `secrets` where each specifies the k8 secret name along with optional `namespace` where the secret resides (the namespace ratify is deployed in will be used as the default value). Along with named secrets being used from the config, the service account linked to the Ratify pod will be queried for associated imagePullSecrets and considered during credential resolution. 
+Goal: Create a Kubernetes Secret Authentication Provider which will use K8s secrets to resolve registry credentials for an artifact. In the `auth-provider` section of the ORAS plugin configuration, the `k8s-secrets` auth-provider contains a list of `secrets` where each specifies the K8s secret name along with optional `namespace` where the secret resides (the namespace ratify is deployed in will be used as the default value). Along with named secrets being used from the config, the service account linked to the Ratify pod will be queried for associated imagePullSecrets and considered during credential resolution. 
 
 The provider will support 2 types of k8s secrets: kubernetes.io/dockercfg, kubernetes.io/dockerconfigjson
 
@@ -111,7 +111,7 @@ type k8SecretAuthProviderConf struct {
 func init() // init calls Register for our k8s-secrets provider
 
 // Create returns a k8AuthProvider instance after parsing auth config and resolving
-// named K8 secrets
+// named K8s secrets
 func (s *k8SecretProviderFactory) Create(authProviderConfig AuthProviderConfig) (AuthProvider, error) {
     // unmarshal the json config for auth provider
     
@@ -130,7 +130,7 @@ func (s *k8SecretProviderFactory) Create(authProviderConfig AuthProviderConfig)
 func (d *k8SecretAuthProvider) Enabled() bool
 
 // Provide finds the secret corresponding to artifact's registryhost,
-// extracts the authentication credentials from k8 secret, and
+// extracts the authentication credentials from K8s secret, and
 // returns AuthConfig
 func (d *k8SecretAuthProvider) Provide(artifact string) (AuthConfig, error) {
     // check provider is properly Enabled
diff --git a/docs/design/Metrics.md b/docs/design/Metrics.md
index 78a0769..010708d 100644
--- a/docs/design/Metrics.md
+++ b/docs/design/Metrics.md
@@ -62,7 +62,7 @@ New Helm values:
 - `metricsType`: string, default: "prometheus"
 - `metricsPort`: int, default: 8888
 
-Corresponding flags for exporter and port will be added to the ratify `serve` command to enable metrics emission in non K8 scenarios. 
+Corresponding flags for exporter and port will be added to the ratify `serve` command to enable metrics emission in non K8s scenarios. 
 
 
 ## Proposed Metrics
diff --git a/docs/discussion/Gatekeeper Timeout Constraint.md b/docs/discussion/Gatekeeper Timeout Constraint.md
index 4cd6ccf..3a0b762 100644
--- a/docs/discussion/Gatekeeper Timeout Constraint.md
+++ b/docs/discussion/Gatekeeper Timeout Constraint.md
@@ -106,7 +106,7 @@ Now in the simple case of a single image signature verification, Ratify complete
 
 ## Questions
 1. Can we extend the timeout?
-Gatekeeper team has advised that this is not feasible since the 3 second timeout is in place to mitigate a k8 leader election issue that occures with a higher timeout. https://github.com/open-policy-agent/gatekeeper/issues/870
+Gatekeeper team has advised that this is not feasible since the 3 second timeout is in place to mitigate a K8s leader election issue that occures with a higher timeout. https://github.com/open-policy-agent/gatekeeper/issues/870
 3. Can we add a retry? Where would we add the retry?
     - kubectl doesn't seem to have retry abilities built in
     - Helm might have something we can leverage? (/cc: Sajay)
diff --git a/internal/constants/constants.go b/internal/constants/constants.go
index 104646f..cc6866e 100644
--- a/internal/constants/constants.go
+++ b/internal/constants/constants.go
@@ -17,3 +17,5 @@ limitations under the License.
 package constants
 
 const RatifyPolicy = "ratify-policy"
+const EmptyNamespace = ""
+const NamespaceSeperator = "/"
diff --git a/pkg/common/oras/authprovider/k8secret_authprovider.go b/pkg/common/oras/authprovider/k8secret_authprovider.go
index 7d15fbe..2c4a71c 100644
--- a/pkg/common/oras/authprovider/k8secret_authprovider.go
+++ b/pkg/common/oras/authprovider/k8secret_authprovider.go
@@ -25,6 +25,8 @@ import (
 	"time"
 
 	re "github.com/deislabs/ratify/errors"
+	"github.com/deislabs/ratify/pkg/utils"
+
 	"github.com/docker/cli/cli/config"
 	core "k8s.io/api/core/v1"
 	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -51,7 +53,6 @@ type k8SecretAuthProviderConf struct {
 }
 
 const defaultName = "default"
-const ratifyNamespaceEnv = "RATIFY_NAMESPACE"
 const secretTimeout = time.Hour * 12
 
 // init calls Register for our k8Secrets provider
@@ -60,7 +61,7 @@ func init() {
 }
 
 // Create returns a k8AuthProvider instance after parsing auth config and resolving
-// named K8 secrets
+// named K8s secrets
 func (s *k8SecretProviderFactory) Create(authProviderConfig AuthProviderConfig) (AuthProvider, error) {
 	conf := k8SecretAuthProviderConf{}
 	authProviderConfigBytes, err := json.Marshal(authProviderConfig)
@@ -87,9 +88,9 @@ func (s *k8SecretProviderFactory) Create(authProviderConfig AuthProviderConfig)
 	}
 
 	// get name of namespace ratify is running in
-	namespace := os.Getenv(ratifyNamespaceEnv)
+	namespace := os.Getenv(utils.RatifyNamespaceEnvVar)
 	if namespace == "" {
-		return nil, re.ErrorCodeEnvNotSet.WithComponentType(re.AuthProvider).WithDetail(fmt.Sprintf("environment variable %s not set", ratifyNamespaceEnv))
+		return nil, re.ErrorCodeEnvNotSet.WithComponentType(re.AuthProvider).WithDetail(fmt.Sprintf("environment variable %s not set", utils.RatifyNamespaceEnvVar))
 	}
 
 	return &k8SecretAuthProvider{
@@ -109,10 +110,10 @@ func (d *k8SecretAuthProvider) Enabled(_ context.Context) bool {
 }
 
 // Provide finds secret corresponding to artifact's registry host name, extracts
-// the authentication credentials from k8 secret, and returns AuthConfig
+// the authentication credentials from K8s secret, and returns AuthConfig
 func (d *k8SecretAuthProvider) Provide(ctx context.Context, artifact string) (AuthConfig, error) {
 	if !d.Enabled(ctx) {
-		return AuthConfig{}, fmt.Errorf("k8 auth provider not properly enabled")
+		return AuthConfig{}, fmt.Errorf("K8s auth provider not properly enabled")
 	}
 
 	hostName, err := GetRegistryHostName(artifact)
diff --git a/pkg/controllers/verifier_controller.go b/pkg/controllers/verifier_controller.go
index a1d6797..c6525db 100644
--- a/pkg/controllers/verifier_controller.go
+++ b/pkg/controllers/verifier_controller.go
@@ -19,13 +19,17 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"os"
 
 	configv1beta1 "github.com/deislabs/ratify/api/v1beta1"
 	"github.com/deislabs/ratify/config"
+	re "github.com/deislabs/ratify/errors"
+	"github.com/deislabs/ratify/pkg/utils"
 	vr "github.com/deislabs/ratify/pkg/verifier"
 	vc "github.com/deislabs/ratify/pkg/verifier/config"
 	vf "github.com/deislabs/ratify/pkg/verifier/factory"
 	"github.com/deislabs/ratify/pkg/verifier/types"
+
 	"github.com/sirupsen/logrus"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -62,6 +66,7 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 
 	var verifier configv1beta1.Verifier
 	var resource = req.Name
+
 	verifierLogger.Infof("reconciling verifier '%v'", resource)
 
 	if err := r.Get(ctx, req.NamespacedName, &verifier); err != nil {
@@ -75,7 +80,13 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 		return ctrl.Result{}, client.IgnoreNotFound(err)
 	}
 
-	if err := verifierAddOrReplace(verifier.Spec, resource); err != nil {
+	namespace, err := getCertStoreNamespace(req.Namespace)
+	if err != nil {
+		verifierLogger.Error(err, "unable to get default namespace for certstore specified in verifier crd")
+		return ctrl.Result{}, err
+	}
+
+	if err = verifierAddOrReplace(verifier.Spec, resource, namespace); err != nil {
 		verifierLogger.Error(err, "unable to create verifier from verifier crd")
 		return ctrl.Result{}, err
 	}
@@ -85,7 +96,7 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 }
 
 // creates a verifier reference from CRD spec and add store to map
-func verifierAddOrReplace(spec configv1beta1.VerifierSpec, objectName string) error {
+func verifierAddOrReplace(spec configv1beta1.VerifierSpec, objectName string, namespace string) error {
 	verifierConfig, err := specToVerifierConfig(spec)
 
 	if err != nil {
@@ -100,7 +111,7 @@ func verifierAddOrReplace(spec configv1beta1.VerifierSpec, objectName string) er
 		spec.Address = config.GetDefaultPluginPath()
 		logrus.Infof("Address was empty, setting to default path: %v", spec.Address)
 	}
-	verifierReference, err := vf.CreateVerifierFromConfig(verifierConfig, verifierConfigVersion, []string{spec.Address})
+	verifierReference, err := vf.CreateVerifierFromConfig(verifierConfig, verifierConfigVersion, []string{spec.Address}, namespace)
 
 	if err != nil || verifierReference == nil {
 		logrus.Error(err, "unable to create verifier from verifier config")
@@ -143,3 +154,20 @@ func (r *VerifierReconciler) SetupWithManager(mgr ctrl.Manager) error {
 		For(&configv1beta1.Verifier{}).
 		Complete(r)
 }
+
+// Historically certStore defined in trust policy only contains name which means the CertStore cannot be uniquely identified
+// If verifierNamesapce is not empty, this method returns the default cert store namespace else returns the ratify deployed namespace
+func getCertStoreNamespace(verifierNamesapce string) (string, error) {
+	// first, check if we can use the verifier namespace
+	if verifierNamesapce != "" {
+		return verifierNamesapce, nil
+	}
+
+	// next, return the ratify deployed namespace
+	ns, found := os.LookupEnv(utils.RatifyNamespaceEnvVar)
+	if !found {
+		return "", re.ErrorCodeEnvNotSet.WithComponentType(re.Verifier).WithDetail(fmt.Sprintf("environment variable %s not set", utils.RatifyNamespaceEnvVar))
+	}
+
+	return ns, nil
+}
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index 7a2fc83..542ad5b 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -27,6 +27,8 @@ import (
 	"github.com/opencontainers/go-digest"
 )
 
+const RatifyNamespaceEnvVar = "RATIFY_NAMESPACE"
+
 // ParseDigest parses the given string and returns a validated Digest object.
 func ParseDigest(digestStr string) (digest.Digest, error) {
 	digest, err := digest.Parse(digestStr)
diff --git a/pkg/verifier/factory/factory.go b/pkg/verifier/factory/factory.go
index 1a0c911..d97bedb 100644
--- a/pkg/verifier/factory/factory.go
+++ b/pkg/verifier/factory/factory.go
@@ -34,7 +34,7 @@ import (
 var builtInVerifiers = make(map[string]VerifierFactory)
 
 type VerifierFactory interface {
-	Create(version string, verifierConfig config.VerifierConfig, pluginDirectory string) (verifier.ReferenceVerifier, error)
+	Create(version string, verifierConfig config.VerifierConfig, pluginDirectory string, namespace string) (verifier.ReferenceVerifier, error)
 }
 
 func Register(name string, factory VerifierFactory) {
@@ -50,7 +50,8 @@ func Register(name string, factory VerifierFactory) {
 }
 
 // returns a single verifier from a verifierConfig
-func CreateVerifierFromConfig(verifierConfig config.VerifierConfig, configVersion string, pluginBinDir []string) (verifier.ReferenceVerifier, error) {
+// namespace is only applicable in K8s environment, namespace is appended to the certstore of the truststore so it is uniquely identifiable in a cluster env
+func CreateVerifierFromConfig(verifierConfig config.VerifierConfig, configVersion string, pluginBinDir []string, namespace string) (verifier.ReferenceVerifier, error) {
 	verifierName, ok := verifierConfig[types.Name]
 	if !ok {
 		return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithDetail(fmt.Sprintf("failed to find verifier name in the verifier config with key %s", "name"))
@@ -82,14 +83,14 @@ func CreateVerifierFromConfig(verifierConfig config.VerifierConfig, configVersio
 
 	verifierFactory, ok := builtInVerifiers[verifierNameStr]
 	if ok {
-		return verifierFactory.Create(configVersion, verifierConfig, pluginBinDir[0])
+		return verifierFactory.Create(configVersion, verifierConfig, pluginBinDir[0], namespace)
 	}
 	return plugin.NewVerifier(configVersion, verifierConfig, pluginBinDir)
 }
 
 // TODO pointer to avoid copy
 // returns an array of verifiers from VerifiersConfig
-func CreateVerifiersFromConfig(verifiersConfig config.VerifiersConfig, defaultPluginPath string) ([]verifier.ReferenceVerifier, error) {
+func CreateVerifiersFromConfig(verifiersConfig config.VerifiersConfig, defaultPluginPath string, namespace string) ([]verifier.ReferenceVerifier, error) {
 	if verifiersConfig.Version == "" {
 		verifiersConfig.Version = types.SpecVersion
 	}
@@ -112,7 +113,7 @@ func CreateVerifiersFromConfig(verifiersConfig config.VerifiersConfig, defaultPl
 
 	// TODO: do we need to append defaultPlugin path?
 	for _, verifierConfig := range verifiersConfig.Verifiers {
-		verifier, err := CreateVerifierFromConfig(verifierConfig, verifiersConfig.Version, verifiersConfig.PluginBinDirs)
+		verifier, err := CreateVerifierFromConfig(verifierConfig, verifiersConfig.Version, verifiersConfig.PluginBinDirs, namespace)
 		if err != nil {
 			return nil, re.ErrorCodePluginInitFailure.WithComponentType(re.Verifier).WithError(err)
 		}
diff --git a/pkg/verifier/notation/notation.go b/pkg/verifier/notation/notation.go
index 5e8b2a0..6d5936f 100644
--- a/pkg/verifier/notation/notation.go
+++ b/pkg/verifier/notation/notation.go
@@ -24,6 +24,7 @@ import (
 
 	ratifyconfig "github.com/deislabs/ratify/config"
 	re "github.com/deislabs/ratify/errors"
+	"github.com/deislabs/ratify/internal/constants"
 	"github.com/deislabs/ratify/internal/logger"
 	"github.com/deislabs/ratify/pkg/common"
 	"github.com/deislabs/ratify/pkg/homedir"
@@ -72,8 +73,9 @@ func init() {
 	factory.Register(verifierName, &notationPluginVerifierFactory{})
 }
 
-func (f *notationPluginVerifierFactory) Create(_ string, verifierConfig config.VerifierConfig, pluginDirectory string) (verifier.ReferenceVerifier, error) {
-	conf, err := parseVerifierConfig(verifierConfig)
+func (f *notationPluginVerifierFactory) Create(_ string, verifierConfig config.VerifierConfig, pluginDirectory string, namespace string) (verifier.ReferenceVerifier, error) {
+	logger.GetLogger(context.Background(), logOpt).Debugf("creating notation with config %v, namespace '%v'", verifierConfig, namespace)
+	conf, err := parseVerifierConfig(verifierConfig, namespace)
 	if err != nil {
 		return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName)
 	}
@@ -170,7 +172,7 @@ func (v *notationPluginVerifier) verifySignature(ctx context.Context, subjectRef
 	return (*v.notationVerifier).Verify(ctx, subjectDesc, refBlob, opts)
 }
 
-func parseVerifierConfig(verifierConfig config.VerifierConfig) (*NotationPluginVerifierConfig, error) {
+func parseVerifierConfig(verifierConfig config.VerifierConfig, namespace string) (*NotationPluginVerifierConfig, error) {
 	conf := &NotationPluginVerifierConfig{}
 
 	verifierConfigBytes, err := json.Marshal(verifierConfig)
@@ -182,6 +184,15 @@ func parseVerifierConfig(verifierConfig config.VerifierConfig) (*NotationPluginV
 		return nil, re.ErrorCodeConfigInvalid.NewError(re.Verifier, verifierName, re.EmptyLink, err, fmt.Sprintf("failed to unmarshal to notationPluginVerifierConfig from: %+v.", verifierConfig), re.HideStackTrace)
 	}
 
+	// append namespace to uniquely identify the certstore
+	if len(conf.VerificationCertStores) > 0 {
+		logger.GetLogger(context.Background(), logOpt).Debugf("VerificationCertStores is not empty, will append namespace %v to certificate store if resource does not already contain a namespace", namespace)
+		conf.VerificationCertStores, err = prependNamespaceToCertStore(conf.VerificationCertStores, namespace)
+		if err != nil {
+			return nil, err
+		}
+	}
+
 	defaultCertsDir := paths.Join(homedir.Get(), ratifyconfig.ConfigFileDir, defaultCertPath)
 	conf.VerificationCerts = append(conf.VerificationCerts, defaultCertsDir)
 	return conf, nil
@@ -191,3 +202,24 @@ func parseVerifierConfig(verifierConfig config.VerifierConfig) (*NotationPluginV
 func (v *notationPluginVerifier) GetNestedReferences() []string {
 	return []string{}
 }
+
+// append namespace to certStore so they are uniquely identifiable
+func prependNamespaceToCertStore(verificationCertStore map[string][]string, namespace string) (map[string][]string, error) {
+	if namespace == "" {
+		return nil, re.ErrorCodeEnvNotSet.WithComponentType(re.Verifier).WithDetail("failure to parse VerificationCertStores, namespace for VerificationCertStores must be provided")
+	}
+
+	for _, certStores := range verificationCertStore {
+		for i, certstore := range certStores {
+			if !isNamespacedNamed(certstore) {
+				certStores[i] = namespace + constants.NamespaceSeperator + certstore
+			}
+		}
+	}
+	return verificationCertStore, nil
+}
+
+// return true if string looks like a K8s namespaced resource. e.g. namespace/name
+func isNamespacedNamed(name string) bool {
+	return strings.Contains(name, constants.NamespaceSeperator)
+}
diff --git a/pkg/verifier/notation/truststore.go b/pkg/verifier/notation/truststore.go
index 95632a3..048c0df 100644
--- a/pkg/verifier/notation/truststore.go
+++ b/pkg/verifier/notation/truststore.go
@@ -54,6 +54,7 @@ func (s trustStore) getCertificatesInternal(ctx context.Context, namedStore stri
 	// certs configured for this namedStore overrides cert path
 	if certGroup := s.certStores[namedStore]; len(certGroup) > 0 {
 		for _, certStore := range certGroup {
+			logger.GetLogger(ctx, logOpt).Debugf("truststore getting certStore %v", certStore)
 			result := certificatesMap[certStore]
 			if len(result) == 0 {
 				logger.GetLogger(ctx, logOpt).Warnf("no certificate fetched for certStore %+v", certStore)
@@ -72,7 +73,7 @@ func (s trustStore) getCertificatesInternal(ctx context.Context, namedStore stri
 			certs = append(certs, bundledCerts...)
 		}
 	}
-
+	logger.GetLogger(ctx, logOpt).Debugf("Trust store getCertificatesInternal , %v certs retrieved", len(certs))
 	return certs, nil
 }
 


Test patch:
diff --git a/pkg/common/oras/authprovider/k8secret_authprovider_test.go b/pkg/common/oras/authprovider/k8secret_authprovider_test.go
index 12f5cc7..c925b31 100644
--- a/pkg/common/oras/authprovider/k8secret_authprovider_test.go
+++ b/pkg/common/oras/authprovider/k8secret_authprovider_test.go
@@ -23,7 +23,7 @@ import (
 	core "k8s.io/api/core/v1"
 )
 
-// Checks K8 Docker Json Config Secret is properly extracted and
+// Checks K8s Docker Json Config Secret is properly extracted and
 // credentials returned when Provide is called
 func TestProvide_K8SecretDockerConfigJson_ReturnsExpected(t *testing.T) {
 	var testSecret core.Secret
diff --git a/pkg/controllers/certificatestore_controller.go b/pkg/controllers/certificatestore_controller.go
index b7c0409..2c60347 100644
--- a/pkg/controllers/certificatestore_controller.go
+++ b/pkg/controllers/certificatestore_controller.go
@@ -65,14 +65,14 @@ const maxBriefErrLength = 30
 func (r *CertificateStoreReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
 	logger := logrus.WithContext(ctx)
 
-	var resource = req.Name
+	var resource = req.NamespacedName.String()
 	var certStore configv1beta1.CertificateStore
 
 	logger.Infof("reconciling certificate store '%v'", resource)
 
 	if err := r.Get(ctx, req.NamespacedName, &certStore); err != nil {
 		if apierrors.IsNotFound(err) {
-			logger.Infof("deletion detected, removing certificate store %v", req.Name)
+			logger.Infof("deletion detected, removing certificate store %v", resource)
 			delete(certificatesMap, resource)
 		} else {
 			logger.Error(err, "unable to fetch certificate store")
diff --git a/pkg/controllers/verifier_controller_test.go b/pkg/controllers/verifier_controller_test.go
index 27086cc..ca4b7f1 100644
--- a/pkg/controllers/verifier_controller_test.go
+++ b/pkg/controllers/verifier_controller_test.go
@@ -20,6 +20,8 @@ import (
 	"testing"
 
 	configv1beta1 "github.com/deislabs/ratify/api/v1beta1"
+	"github.com/deislabs/ratify/internal/constants"
+	"github.com/deislabs/ratify/pkg/utils"
 	vr "github.com/deislabs/ratify/pkg/verifier"
 	"k8s.io/apimachinery/pkg/runtime"
 )
@@ -39,7 +41,7 @@ func TestVerifierAdd_EmptyParameter(t *testing.T) {
 	}
 	var resource = "notation"
 
-	if err := verifierAddOrReplace(testVerifierSpec, resource); err != nil {
+	if err := verifierAddOrReplace(testVerifierSpec, resource, constants.EmptyNamespace); err != nil {
 		t.Fatalf("verifierAddOrReplace() expected no error, actual %v", err)
 	}
 	if len(VerifierMap) != 1 {
@@ -55,7 +57,7 @@ func TestVerifierAdd_WithParameters(t *testing.T) {
 
 	var testVerifierSpec = getDefaultLicenseCheckerSpec()
 
-	if err := verifierAddOrReplace(testVerifierSpec, "testObject"); err != nil {
+	if err := verifierAddOrReplace(testVerifierSpec, "testObject", constants.EmptyNamespace); err != nil {
 		t.Fatalf("verifierAddOrReplace() expected no error, actual %v", err)
 	}
 	if len(VerifierMap) != 1 {
@@ -70,7 +72,7 @@ func TestVerifier_UpdateAndDelete(t *testing.T) {
 	var testVerifierSpec = getDefaultLicenseCheckerSpec()
 
 	// add a verifier
-	if err := verifierAddOrReplace(testVerifierSpec, resource); err != nil {
+	if err := verifierAddOrReplace(testVerifierSpec, resource, constants.EmptyNamespace); err != nil {
 		t.Fatalf("verifierAddOrReplace() expected no error, actual %v", err)
 	}
 	if len(VerifierMap) != 1 {
@@ -80,7 +82,7 @@ func TestVerifier_UpdateAndDelete(t *testing.T) {
 	// modify the verifier
 	var parametersString = "{\"allowedLicenses\":[\"MIT\",\"GNU\"]}"
 	testVerifierSpec = getLicenseCheckerFromParam(parametersString)
-	if err := verifierAddOrReplace(testVerifierSpec, resource); err != nil {
+	if err := verifierAddOrReplace(testVerifierSpec, resource, constants.EmptyNamespace); err != nil {
 		t.Fatalf("verifierAddOrReplace() expected no error, actual %v", err)
 	}
 
@@ -96,6 +98,31 @@ func TestVerifier_UpdateAndDelete(t *testing.T) {
 	}
 }
 
+func TestGetCertStoreNamespace(t *testing.T) {
+	// error scenario, everything is empty, expect error
+	_, err := getCertStoreNamespace("")
+	if err.Error() == "environment variable" {
+		t.Fatalf("env not set should trigger an error")
+	}
+
+	ratifyDeployedNamespace := "sample"
+	os.Setenv(utils.RatifyNamespaceEnvVar, ratifyDeployedNamespace)
+	defer os.Unsetenv(utils.RatifyNamespaceEnvVar)
+
+	// scenario1, when default namespace is provided, then we should expect default
+	verifierNamespace := "verifierNamespace"
+	ns, _ := getCertStoreNamespace(verifierNamespace)
+	if ns != verifierNamespace {
+		t.Fatalf("default namespace expected")
+	}
+
+	// scenario2, default is empty, should return ratify installed namespace
+	ns, _ = getCertStoreNamespace("")
+	if ns != ratifyDeployedNamespace {
+		t.Fatalf("default namespace expected")
+	}
+}
+
 func resetVerifierMap() {
 	VerifierMap = map[string]vr.ReferenceVerifier{}
 }
diff --git a/pkg/verifier/factory/factory_test.go b/pkg/verifier/factory/factory_test.go
index 53fbc0a..6058a0a 100644
--- a/pkg/verifier/factory/factory_test.go
+++ b/pkg/verifier/factory/factory_test.go
@@ -19,6 +19,7 @@ import (
 	"context"
 	"testing"
 
+	"github.com/deislabs/ratify/internal/constants"
 	"github.com/deislabs/ratify/pkg/common"
 	"github.com/deislabs/ratify/pkg/ocispecs"
 	"github.com/deislabs/ratify/pkg/referrerstore"
@@ -52,7 +53,7 @@ func (s *TestVerifier) GetNestedReferences() []string {
 	return []string{}
 }
 
-func (f *TestVerifierFactory) Create(_ string, _ config.VerifierConfig, pluginDirectory string) (verifier.ReferenceVerifier, error) {
+func (f *TestVerifierFactory) Create(_ string, _ config.VerifierConfig, pluginDirectory string, _ string) (verifier.ReferenceVerifier, error) {
 	return &TestVerifier{verifierDirectory: pluginDirectory}, nil
 }
 
@@ -68,7 +69,7 @@ func TestCreateVerifiersFromConfig_BuiltInVerifiers_ReturnsExpected(t *testing.T
 		Verifiers: []config.VerifierConfig{verifierConfig},
 	}
 
-	verifiers, err := CreateVerifiersFromConfig(verifiersConfig, "test/dir")
+	verifiers, err := CreateVerifiersFromConfig(verifiersConfig, "test/dir", constants.EmptyNamespace)
 
 	if err != nil {
 		t.Fatalf("create verifiers failed with err %v", err)
@@ -103,7 +104,7 @@ func TestCreateVerifiersFromConfig_PluginVerifiers_ReturnsExpected(t *testing.T)
 		Verifiers: []config.VerifierConfig{verifierConfig},
 	}
 
-	verifiers, err := CreateVerifiersFromConfig(verifiersConfig, "")
+	verifiers, err := CreateVerifiersFromConfig(verifiersConfig, "", "")
 
 	if err != nil {
 		t.Fatalf("create verifiers failed with err %v", err)
diff --git a/pkg/verifier/notation/notation_test.go b/pkg/verifier/notation/notation_test.go
index cf7afec..d7eb7fc 100644
--- a/pkg/verifier/notation/notation_test.go
+++ b/pkg/verifier/notation/notation_test.go
@@ -226,7 +226,7 @@ func TestParseVerifierConfig(t *testing.T) {
 				"name":              test,
 				"verificationCerts": []string{testPath},
 				"verificationCertStores": map[string][]string{
-					"certstore1": {"akv1", "akv2"},
+					"certstore1": {"defaultns/akv1", "akv2"},
 					"certstore2": {"akv3", "akv4"},
 				},
 			},
@@ -235,8 +235,8 @@ func TestParseVerifierConfig(t *testing.T) {
 				Name:              test,
 				VerificationCerts: []string{testPath, defaultCertDir},
 				VerificationCertStores: map[string][]string{
-					"certstore1": {"akv1", "akv2"},
-					"certstore2": {"akv3", "akv4"},
+					"certstore1": {"defaultns/akv1", "testns/akv2"},
+					"certstore2": {"testns/akv3", "testns/akv4"},
 				},
 			},
 		},
@@ -245,7 +245,7 @@ func TestParseVerifierConfig(t *testing.T) {
 	//TODO add new test for parseVerifierConfig
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			notationPluginConfig, err := parseVerifierConfig(tt.configMap)
+			notationPluginConfig, err := parseVerifierConfig(tt.configMap, "testns")
 
 			if (err != nil) != tt.expectErr {
 				t.Errorf("error = %v, expectErr = %v", err, tt.expectErr)
@@ -306,7 +306,7 @@ func TestCreate(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			f := &notationPluginVerifierFactory{}
-			_, err := f.Create(testVersion, tt.configMap, "")
+			_, err := f.Create(testVersion, tt.configMap, "", "")
 
 			if (err != nil) != tt.expectErr {
 				t.Fatalf("error = %v, expectErr = %v", err, tt.expectErr)
diff --git a/pkg/verifier/notation/truststore_test.go b/pkg/verifier/notation/truststore_test.go
index d767c24..5a0b727 100644
--- a/pkg/verifier/notation/truststore_test.go
+++ b/pkg/verifier/notation/truststore_test.go
@@ -32,8 +32,8 @@ func TestGetCertificates_EmptyCertMap(t *testing.T) {
 
 func TestGetCertificates_NamedStore(t *testing.T) {
 	certStore := map[string][]string{}
-	certStore["store1"] = []string{"kv1"}
-	certStore["store2"] = []string{"kv2"}
+	certStore["store1"] = []string{"default/kv1"}
+	certStore["store2"] = []string{"projecta/kv2"}
 
 	store := &trustStore{
 		certStores: certStore,
@@ -43,8 +43,8 @@ func TestGetCertificates_NamedStore(t *testing.T) {
 	kv2Cert := getCert(certStr2)
 
 	certificatesMap := map[string][]*x509.Certificate{}
-	certificatesMap["kv1"] = []*x509.Certificate{kv1Cert}
-	certificatesMap["kv2"] = []*x509.Certificate{kv2Cert}
+	certificatesMap["default/kv1"] = []*x509.Certificate{kv1Cert}
+	certificatesMap["projecta/kv2"] = []*x509.Certificate{kv2Cert}
 
 	// only the certificate in the specified namedStore should be returned
 	result, _ := store.getCertificatesInternal(context.Background(), "store1", certificatesMap)
diff --git a/test/bats/azure-test.bats b/test/bats/azure-test.bats
index deb3ac1..bf68b41 100644
--- a/test/bats/azure-test.bats
+++ b/test/bats/azure-test.bats
@@ -247,7 +247,7 @@ SLEEP_TIME=1
 }
 
 @test "configmap update test" {
-    skip "Skipping test for now as we are no longer watching for configfile update in a k8 environment.This test ensures we are watching config file updates in a non-kub scenario"
+    skip "Skipping test for now as we are no longer watching for configfile update in a K8s environment.This test ensures we are watching config file updates in a non-kub scenario"
     run kubectl apply -f ./library/default/template.yaml
     assert_success
     sleep 5
diff --git a/test/bats/base-test.bats b/test/bats/base-test.bats
index 6eabec4..4f693cc 100644
--- a/test/bats/base-test.bats
+++ b/test/bats/base-test.bats
@@ -5,6 +5,7 @@ load helpers
 BATS_TESTS_DIR=${BATS_TESTS_DIR:-test/bats/tests}
 WAIT_TIME=60
 SLEEP_TIME=1
+RATIFY_NAMESPACE=gatekeeper-system
 
 @test "base test without cert rotator" {
     teardown() {
@@ -21,7 +22,7 @@ SLEEP_TIME=1
     assert_success
     sleep 5
     # validate certificate store status property shows success
-    run bash -c "kubectl get certificatestores.config.ratify.deislabs.io/ratify-notation-inline-cert -n gatekeeper-system -o yaml | grep 'issuccess: true'"
+    run bash -c "kubectl get certificatestores.config.ratify.deislabs.io/ratify-notation-inline-cert -n ${RATIFY_NAMESPACE} -o yaml | grep 'issuccess: true'"
     assert_success
     run kubectl run demo --namespace default --image=registry:5000/notation:signed
     assert_success
@@ -72,9 +73,53 @@ SLEEP_TIME=1
     run kubectl apply -f ./library/default/samples/constraint.yaml
     assert_success
     sleep 5
+
     # validate certificate store status property shows success
-    run bash -c "kubectl get certificatestores.config.ratify.deislabs.io/ratify-notation-inline-cert -n gatekeeper-system -o yaml | grep 'issuccess: true'"
+    run bash -c "kubectl get certificatestores.config.ratify.deislabs.io/ratify-notation-inline-cert -n ${RATIFY_NAMESPACE} -o yaml | grep 'issuccess: true'"
+    assert_success
+    run kubectl run demo --namespace default --image=registry:5000/notation:signed
+    assert_success
+
+    run kubectl run demo1 --namespace default --image=registry:5000/notation:unsigned
+    assert_failure
+}
+
+@test "notation test with certs across namespace" {
+    teardown() {
+        echo "cleaning up"
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete pod demo --namespace default --force --ignore-not-found=true'
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete pod demo1 --namespace default --force --ignore-not-found=true'
+        
+        # restore cert store in ratify namespace
+        run bash -c "kubectl get certificatestores.config.ratify.deislabs.io/ratify-notation-inline-cert -o yaml -n default > certStore.yaml"
+        run kubectl delete certificatestores.config.ratify.deislabs.io/ratify-notation-inline-cert -n default
+        sed 's/default/gatekeeper-system/' certStore.yaml > certStoreNewNS.yaml
+        run kubectl apply -f certStoreNewNS.yaml        
+        assert_success
+
+        # restore the original notation verifier for other tests
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl apply -f ./config/samples/config_v1beta1_verifier_notation.yaml'
+    }
+    run kubectl apply -f ./library/default/template.yaml
+    assert_success
+    sleep 5
+    run kubectl apply -f ./library/default/samples/constraint.yaml
     assert_success
+    sleep 5
+    
+    # apply the certstore to default namespace
+    run bash -c "kubectl get certificatestores.config.ratify.deislabs.io/ratify-notation-inline-cert -o yaml -n ${RATIFY_NAMESPACE} > certStore.yaml"    
+    assert_success
+    sed 's/gatekeeper-system/default/' certStore.yaml > certStoreNewNS.yaml    
+    run kubectl apply -f certStoreNewNS.yaml
+    assert_success
+    run kubectl delete certificatestores.config.ratify.deislabs.io/ratify-notation-inline-cert -n ${RATIFY_NAMESPACE}
+    assert_success
+    
+    # configure the notation verifier to use inline certificate store with specific namespace
+    run kubectl apply -f ./config/samples/config_v1beta1_verifier_notation_specificnscertstore.yaml
+    assert_success
+
     run kubectl run demo --namespace default --image=registry:5000/notation:signed
     assert_success
 
@@ -109,7 +154,7 @@ SLEEP_TIME=1
 }
 
 @test "configmap update test" {
-    skip "Skipping test for now as we are no longer watching for configfile update in a k8 environment. This test ensures we are watching config file updates in a non-kub scenario"
+    skip "Skipping test for now as we are no longer watching for configfile update in a K8s environment. This test ensures we are watching config file updates in a non-kub scenario"
     run kubectl apply -f ./library/default/template.yaml
     assert_success
     sleep 5
@@ -119,10 +164,10 @@ SLEEP_TIME=1
     run kubectl run demo2 --image=registry:5000/notation:signed
     assert_success
 
-    run kubectl get configmaps ratify-configuration --namespace=gatekeeper-system -o yaml >currentConfig.yaml
+    run kubectl get configmaps ratify-configuration --namespace=${RATIFY_NAMESPACE} -o yaml >currentConfig.yaml
     run kubectl delete -f ./library/default/samples/constraint.yaml
 
-    wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl replace --namespace=gatekeeper-system -f ${BATS_TESTS_DIR}/configmap/invalidconfigmap.yaml"
+    wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl replace --namespace=${RATIFY_NAMESPACE} -f ${BATS_TESTS_DIR}/configmap/invalidconfigmap.yaml"
     echo "Waiting for 150 second for configuration update"
     sleep 150
 
@@ -132,7 +177,7 @@ SLEEP_TIME=1
     echo "Current time after validate : $(date +"%T")"
     assert_failure
 
-    wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl replace --namespace=gatekeeper-system -f currentConfig.yaml"
+    wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl replace --namespace=${RATIFY_NAMESPACE} -f currentConfig.yaml"
 }
 
 @test "validate mutation tag to digest" {
@@ -174,7 +219,7 @@ SLEEP_TIME=1
 
     # add the alternate certificate as an inline certificate store
     cat ~/.config/notation/truststore/x509/ca/alternate-cert/alternate-cert.crt | sed 's/^/      /g' >>./test/bats/tests/config/config_v1beta1_certstore_inline.yaml
-    run kubectl apply -f ./test/bats/tests/config/config_v1beta1_certstore_inline.yaml
+    run kubectl apply -f ./test/bats/tests/config/config_v1beta1_certstore_inline.yaml --namespace ${RATIFY_NAMESPACE}
     assert_success
     sed -i '9,$d' ./test/bats/tests/config/config_v1beta1_certstore_inline.yaml
 
@@ -188,7 +233,7 @@ SLEEP_TIME=1
     assert_success
 }
 
-@test "validate k8 secrets ORAS auth provider" {
+@test "validate K8s secrets ORAS auth provider" {
     teardown() {
         echo "cleaning up"
         wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete pod demo --namespace default --ignore-not-found=true'
@@ -202,7 +247,7 @@ SLEEP_TIME=1
     run kubectl apply -f ./library/default/samples/constraint.yaml
     assert_success
     sleep 5
-    # apply store CRD with k8 secret auth provier enabled
+    # apply store CRD with K8s secret auth provier enabled
     run kubectl apply -f ./config/samples/config_v1beta1_store_oras_k8secretAuth.yaml
     assert_success
     sleep 5
@@ -214,7 +259,7 @@ SLEEP_TIME=1
 
 @test "validate image signed by leaf cert" {
     teardown() {
-        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete certificatestores.config.ratify.deislabs.io/certstore-inline --namespace default --ignore-not-found=true'
+        wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete certificatestores.config.ratify.deislabs.io/certstore-inline --namespace ${RATIFY_NAMESPACE} --ignore-not-found=true'
         wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete pod demo-leaf --namespace default --force --ignore-not-found=true'
         wait_for_process ${WAIT_TIME} ${SLEEP_TIME} 'kubectl delete pod demo-leaf2 --namespace default --force --ignore-not-found=true'
 
@@ -230,7 +275,7 @@ SLEEP_TIME=1
 
     # add the root certificate as an inline certificate store
     cat ~/.config/notation/truststore/x509/ca/leaf-test/root.crt | sed 's/^/      /g' >>./test/bats/tests/config/config_v1beta1_certstore_inline.yaml
-    run kubectl apply -f ./test/bats/tests/config/config_v1beta1_certstore_inline.yaml
+    run kubectl apply -f ./test/bats/tests/config/config_v1beta1_certstore_inline.yaml --namespace ${RATIFY_NAMESPACE}
     assert_success
     sed -i '9,$d' ./test/bats/tests/config/config_v1beta1_certstore_inline.yaml
 
@@ -244,7 +289,7 @@ SLEEP_TIME=1
 
     # add the root certificate as an inline certificate store
     cat ~/.config/notation/truststore/x509/ca/leaf-test/leaf.crt | sed 's/^/      /g' >>./test/bats/tests/config/config_v1beta1_certstore_inline.yaml
-    run kubectl apply -f ./test/bats/tests/config/config_v1beta1_certstore_inline.yaml
+    run kubectl apply -f ./test/bats/tests/config/config_v1beta1_certstore_inline.yaml --namespace ${RATIFY_NAMESPACE}
     assert_success
     sed -i '9,$d' ./test/bats/tests/config/config_v1beta1_certstore_inline.yaml
 
@@ -265,10 +310,10 @@ SLEEP_TIME=1
     run kubectl get Provider ratify-provider -o json | jq --arg ca "$(cat .staging/rotation/ca.crt | base64)" '.spec.caBundle=$ca' | kubectl replace -f -
 
     # update the ratify tls secret to use the new tls cert and key
-    run kubectl get secret ratify-tls -n gatekeeper-system -o json | jq --arg cert "$(cat .staging/rotation/server.crt | base64)" --arg key "$(cat .staging/rotation/server.key | base64)" '.data["tls.key"]=$key | .data["tls.crt"]=$cert' | kubectl replace -f -
+    run kubectl get secret ratify-tls -n ${RATIFY_NAMESPACE} -o json | jq --arg cert "$(cat .staging/rotation/server.crt | base64)" --arg key "$(cat .staging/rotation/server.key | base64)" '.data["tls.key"]=$key | .data["tls.crt"]=$cert' | kubectl replace -f -
 
     # update the gatekeeper webhook server tls secret to use the new cert bundle
-    run kubectl get Secret gatekeeper-webhook-server-cert -n gatekeeper-system -o json | jq --arg caCert "$(cat .staging/rotation/gatekeeper/ca.crt | base64)" --arg caKey "$(cat .staging/rotation/gatekeeper/ca.key | base64)" --arg tlsCert "$(cat .staging/rotation/gatekeeper/server.crt | base64)" --arg tlsKey "$(cat .staging/rotation/gatekeeper/server.key | base64)" '.data["ca.crt"]=$caCert | .data["ca.key"]=$caKey | .data["tls.crt"]=$tlsCert | .data["tls.key"]=$tlsKey' | kubectl replace -f -
+    run kubectl get Secret gatekeeper-webhook-server-cert -n ${RATIFY_NAMESPACE} -o json | jq --arg caCert "$(cat .staging/rotation/gatekeeper/ca.crt | base64)" --arg caKey "$(cat .staging/rotation/gatekeeper/ca.key | base64)" --arg tlsCert "$(cat .staging/rotation/gatekeeper/server.crt | base64)" --arg tlsKey "$(cat .staging/rotation/gatekeeper/server.key | base64)" '.data["ca.crt"]=$caCert | .data["ca.key"]=$caKey | .data["tls.crt"]=$tlsCert | .data["tls.key"]=$tlsKey' | kubectl replace -f -
 
     # volume projection can take up to 90 seconds
     sleep 100