How to have a single user with access to multiple namespaces with separate certs for each namespace

3/28/2019

I'm trying to setup some basic Authorization and Authentication for various users to access a shared K8s cluster.

Requirement: Multiple users can have access to multiple namespaces with a separate set of cert and keys for each of them.

Proposal:

openssl genrsa -out $PRIV_KEY 2048

# Generate CSR
openssl req -new -key $PRIV_KEY -out $CSR -subj "/CN=$USER"

# Create k8s CSR

K8S_CSR=user-request-$USER-$NAMESPACE_NAME-admin

cat <<EOF >./$K8S_CSR.yaml
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: $K8S_CSR
spec:
  groups:
  - system:authenticated
  request: $(cat $CSR | base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - client auth
EOF

kubectl create -n $NAMESPACE_NAME -f $K8S_CSR.yaml

# Approve K8s CSR
kubectl certificate approve $K8S_CSR

# Fetch User Certificate
kubectl get csr $K8S_CSR  -o jsonpath='{.status.certificate}' | base64 -d > $USER-$NAMESPACE_NAME-admin.crt

# Create Admin Role Binding
kubectl create rolebinding $NAMESPACE_NAME-$USER-admin-binding --clusterrole=admin --user=$USER --namespace=$NAMESPACE_NAME

Problem: The user cert and/or pkey are not specific to this namespace. If I just create another rolebinding for the same user in a different namespace he will able to authenticate. How do I prevent that from happening?

-- silent phantom
kubernetes
rbac

1 Answer

3/28/2019

The CA in Kubernetes is a cluster-wide CA (not namespaced) so you won't be able to create certs tied to a specific namespace.

system:authenticated and system:unauthenticated are built-in groups in Kubernetes to identify whether a Role or ClusterRole is authenticated. And you can't directly manager groups or users in Kubernetes. You will have to configure an alternative cluster authentication methods to take advantage of users and groups. For example, a static token file or OpenID

Then you can, restrict users or groups defined in your identity provider to a Role that doesn't allow them to create either another Role or RoleBinding, that way they are not able to give themselves access to other namespaces and only the cluster-admin is the one who decides which RoleBindings (or namespaces) that specific user is part of.

For example, in your Role:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: mynamespace
  name: myrole
rules:
- apiGroups: ["extensions", "apps"]
  resources: ["deployments"] <== never include role, clusterrole, rolebinding, and clusterrolebinding.
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

Another alternative is to restrict base on a Service Account Token by RoleBinding to the service account.

-- Rico
Source: StackOverflow