Limit access of services deployed in Kubernetes namespace

12/26/2021

Let us assume we are the owners of a Kubernetes cluster and we give other users in our organization access to individual namespaces, so they are not supposed to know what is going on in other namespaces.

If user A deploys a certain ressource like a Grafana-Prometheus monitoring stack to namespace A, how do we ensure that he cannot see with the monitoring stack anything from namespace B, where he should not have any access to.

Of course, we will have to limit the rights of user A anyhow, but how do we automatically limit the rights of it's deployed ressources in namespace A? In case you have any suggestions perhaps with some Kubernetes configuration examples, that would be great.

-- tobias
kubernetes
namespaces
rbac
user-roles
yaml

1 Answer

12/26/2021

The most important aspect of this question is to control the access permission of the service accounts which will be used in the Pods and a network policy which will limit the traffic within the namespace.

Hence we arrive to this algorithm:

Prerequisite: Creating the user and namespace

sudo useradd user-a
kubectl create ns ns-user-a
  1. limiting access permission of user-a to the namespace ns-user-a.
kubectl create clusterrole permission-users --verb=* --resource=*
kubectl create rolebinding permission-users-a --clusterrole=permission-users --user=user-a --namespace=ns-user-a
  1. limiting all the service accounts access permission of namespace ns-user-a.
kubectl create clusterrole permission-serviceaccounts --verb=* --resource=*
kubectl create rolebinding permission-serviceaccounts --clusterrole=permission-serviceaccounts --namespace=ns-user-a --group=system:serviceaccounts:ns-user-a
kubectl auth can-i create pods  --namespace=ns-user-a --as-group=system:serviceaccounts:ns-user-a --as sa
  1. A network policy in namespace ns-user-a to limit incoming traffic from other namespaces.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-from-other-namespaces
  namespace: ns-user-a
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}

Edit: Allowing traffic from selective namespaces

Assign a label to the monitoring namespace with a custom label.

kubectl label ns monitoring nsname=monitoring

Or, use the following reserved labels from kubernetes to make sure nobody can edit or update this label. So by convention this label should have "monitoring" as assigned value for the "monitoring" namespace.

https://kubernetes.io/docs/reference/labels-annotations-taints/#kubernetes-io-metadata-name

kubernetes.io/metadata.name

Applying a network policy to allow traffic from internal and monitoring namespace.

Note: Network policies always add up. So you can keep both or you can only keep the new one. I am keeping both here, for example purposes.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-only-monitoring-and-inernal
  namespace: ns-user-a
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}    # allows traffic from ns-user-a namespace (same as earlier)
    - namespaceSelector: # allows traffic from monitoring namespace
        matchLabels:
          kubernetes.io/metadata.name: monitoring
-- Rajesh Dutta
Source: StackOverflow