I saw many answers and many articles on the internet saying it's not possible to access the secrets of other namespaces.
However, the answer provided in another question How allow pod from default namespace, read secret from other namespace suggests that it is actually possible by using the correct RBAC role bindings for the service account.
I know it's not the recommended way and you need to be very careful that secrets are not leaked by these measures. But I prefer such an option to manually copy or automatically sync secrets as suggested in other questions.
The missing puzzle piece I'm missing from that answer is, how to inject such a secret as an environment variable in a deployment using secretKeyRef
and accessing it without calling the Kubernetes API?
I've created two namespaces ns1
and ns2
, a secret sec
in ns1, a service account sa
in ns2. See yaml below:
---
apiVersion: v1
kind: Namespace
metadata:
name: ns1
---
apiVersion: v1
kind: Namespace
metadata:
name: ns2
---
apiVersion: v1
kind: Secret
metadata:
name: sec
namespace: ns1
stringData:
key: value
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa
namespace: ns2
Trying to the the secret with kubectl
is not working as expected:
$ kubectl get secrets sec -n ns1 --as system:serviceaccount:ns2:sa
Error from server (Forbidden): secrets "sec" is forbidden: User "system:serviceaccount:ns2:sa" cannot get resource "secrets" in API group "" in the namespace "ns1"
By adding the the required ClusterRole and ClusterRolebinding, the access is possible:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: role-for-sa
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rolebinding-for-sa
namespace: ns1
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: role-for-sa
subjects:
- kind: ServiceAccount
name: sa
namespace: ns2
$ kubectl get secrets sec -n ns1 --as system:serviceaccount:ns2:sa
NAME TYPE DATA AGE
sec Opaque 1 8m27s
So far so good.
Now I want to use that secret in a Pod in ns2 by using secretKeyRef
and specifying the service account to be used:
---
apiVersion: v1
kind: Pod
metadata:
name: envpod
namespace: ns2
spec:
serviceAccountName: sa
containers:
- command:
- sleep
- infinity
image: bitnami/kubectl
name: envpod
env:
- name: MySecret
valueFrom:
secretKeyRef:
key: "key"
name: sec
resources: {}
But during the pod startup I get the error message Error: secret "sec" not found
.
$ kubectl -n ns2 describe pods envpod
...
Warning Failed 8s (x2 over 10s) kubelet Error: secret "sec" not found
...
I tried it also with sec.ns1
but didn't help either.
Any suggestion on how to achieve this? Or explanation why this is not possible that way?
Loading environment variable from a secret object from different namespace is not supported out of the box. You Need to use a startup script ( docker entrypoint ) to fetch the secret object from remote namespace and load them as environment variable inside the pod and then start the main process in the pod