Kubernetes: How to Share Secrets Between Namespaces

Updated: January 31, 2024 By: Guest Contributor Post a comment

Introduction

Managing confidential data such as passwords, OAuth tokens, and ssh keys is crucial in any application setup. In Kubernetes, Secrets are used to hold this sensitive data, and by default, they are isolated to the namespace they are created in. However, scenarios often require these secrets to be accessible across multiple namespaces. In this guide, we will cover methods to share Kubernetes Secrets between different namespaces.

Understanding Kubernetes Secrets

Before we delve into sharing Secrets, let’s first understand what they are. Kubernetes Secrets let you store and manage sensitive information, like passwords, OAuth tokens, and ssh keys. Storing this sensitive information in Secrets is more secure than plaintext ConfigMaps or in Pod specifications.


# Example of creating a generic Secret
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  namespace: default
type: Opaque
data:
  password: $(echo -n "mypassword" | base64)
EOF

Method 1: Copying Secrets

The most straightforward method for sharing a secret is to recreate it in another namespace. This can be achieved by getting the secret from the source namespace and then applying it to the target namespace with a minor change to its metadata:


# Export the Secret from the existing namespace
cubectl get secret mysecret -n default -o yaml |
  grep -v '^
# Create the Secret in the new namespace with kubectl
cat secret.yaml | kubectl create -n mynewnamespace -f -

Although this method is simple, it’s not efficient or secure since it requires manual handling of secret data and doesn’t auto-update with changes to the original secret.

Method 2: Syncing Secrets using a Controller

For more advanced use cases, a secret-sharing controller, like vault-secrets-operator, can dynamically replicate secrets to other namespaces.


# Example: Using a secret replication controller
apiVersion: ricoberger.de/v1alpha1
kind: SecretMirror
metadata:
  name: mirror-mysecret
spec:
  secretName: mysecret
  fromNamespace: default
  to:
    - namespace: mynewnamespace

The secret will automatically be mirrored to the specified namespace, and any changes to the original secret will be propagated. Implementing such a solution requires deploying additional resources and configuring RBAC appropriately.

Method 3: Service Accounts and Role-Based Access Control

A more secure approach is using Kubernetes Role-Based Access Control (RBAC) to grant a service account in one namespace access to secrets in another. The following is an example of how you can create a service account and appropriate roles and bindings.


# Create service account in the target namespace
kubectl create sa myserviceaccount -n mynewnamespace 

The service account can then be granted access with the appropriate roles and role bindings:


# Role that allows access to secret
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: mynewnamespace
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

Conclusion

Sharing Kubernetes Secrets between namespaces involves consideration of security and maintenance implications. While copying is easy, it’s inefficient and potentially insecure. Automation with a controller ensures synchronization but adds complexity. Leveraging RBAC with Service Accounts provides a more secure and controllable method. Choose the approach that best aligns with your operational requirements and security posture.