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

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

<p><em>Proposal</em>:</p>

<pre><code>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 &lt;&lt;EOF &gt;./$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 &gt; $USER-$NAMESPACE_NAME-admin.crt

# Create Admin Role Binding
kubectl create rolebinding $NAMESPACE_NAME-$USER-admin-binding --clusterrole=admin --user=$USER --namespace=$NAMESPACE_NAME
</code></pre>

<p><em>Problem</em>:
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?</p>

<p>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. </p>

<p><code>system:authenticated</code> and <code>system:unauthenticated</code> are built-in groups in Kubernetes to identify whether a <code>Role</code> or <code>ClusterRole</code> is authenticated. And you <a href="https://stackoverflow.com/a/44764979/2989261">can't directly manager groups or users in Kubernetes</a>.  You will have to configure an alternative cluster authentication methods to take advantage of users and groups. For example, a <a href="https://kubernetes.io/docs/reference/access-authn-authz/authentication/#static-token-file" rel="nofollow noreferrer">static token file</a> or <a href="https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens" rel="nofollow noreferrer">OpenID</a></p>

<p>Then you can, restrict users or groups defined in your identity provider to a <code>Role</code> that doesn't allow them to create either another <code>Role</code> or <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding" rel="nofollow noreferrer"><code>RoleBinding</code></a>, that way they are not able to give themselves access to other namespaces and only the cluster-admin is the one who decides which <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding" rel="nofollow noreferrer"><code>RoleBindings</code></a> (or namespaces) that specific user is part of.</p>

<p>For example, in your <code>Role</code>:</p>

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

<p>Another alternative is to restrict base on a <a href="https://kubernetes.io/docs/reference/access-authn-authz/authentication/#static-token-file" rel="nofollow noreferrer">Service Account Token</a> by <code>RoleBinding</code> to the service account.</p>
