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?
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.