Rancher namespaces are the secret sauce for isolating your Kubernetes resources, and when it comes to sensitive data like credentials, Namespaced Secrets are your best friend.
Let’s see it in action. Imagine you’re running two distinct applications on your Rancher cluster: a frontend service and a backend API. Each needs its own database password, but you absolutely do not want the frontend to accidentally get its hands on the backend’s database credentials.
Here’s how you’d set that up.
First, create your namespaces:
kubectl create namespace frontend-app
kubectl create namespace backend-app
Now, let’s create a secret for the frontend’s database. We’ll put it in the frontend-app namespace.
kubectl create secret generic frontend-db-credentials \
--namespace frontend-app \
--from-literal=username=frontend_user \
--from-literal=password='supersecretfrontendpassword123'
And a separate secret for the backend, strictly confined to the backend-app namespace:
kubectl create secret generic backend-db-credentials \
--namespace backend-app \
--from-literal=username=backend_admin \
--from-literal=password='supersecretbackendpassword456'
Your frontend deployment would then reference its secret like this, within its frontend-app namespace:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-deployment
namespace: frontend-app
spec:
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend-container
image: nginx:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: frontend-db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: frontend-db-credentials
key: password
And your backend deployment, in its backend-app namespace, would reference its own:
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-deployment
namespace: backend-app
spec:
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend-container
image: postgres:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: backend-db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: backend-db-credentials
key: password
Notice how the frontend-deployment can only see frontend-db-credentials because it’s in the same namespace. If you tried to deploy the frontend into the backend-app namespace and have it reference frontend-db-credentials, it would fail because the secret doesn’t exist in that scope. This strict scoping is the core of how Namespaced Secrets protect your sensitive information.
The problem these solve is obvious: how do you securely store and distribute credentials, API keys, TLS certificates, and other sensitive configuration data to your applications without embedding them directly in your container images or deployment manifests? Kubernetes Secrets are the answer, and by leveraging Namespaces, you create logical boundaries that prevent cross-application data leakage. By default, all Kubernetes resources, including Secrets, are scoped to a namespace. This means a Pod running in namespace-a can only access Secrets that are also defined within namespace-a. If a Pod needs a Secret, it must explicitly reference it by name and key, and that Secret must reside in the Pod’s own namespace. This isolation is fundamental to multi-tenancy and secure application deployments.
What most people don’t realize is that even though Secrets are base64 encoded (which is not encryption), the true security comes from the RBAC (Role-Based Access Control) policies that govern who or what can read those Secrets. A Service Account associated with a Pod needs a specific get or list permission on secrets within its namespace to access them. Without that explicit permission, the Pod won’t be able to retrieve the Secret’s data, even if it knows the Secret’s name.
The next step is understanding how to manage these secrets using tools like Vault or external secret operators for more advanced lifecycle management and rotation.