<p>I've created a Kubernetes cluster on AWS with <a href="https://github.com/kubernetes/kops" rel="noreferrer">kops</a> and can successfully administer it via <code>kubectl</code> from my local machine.</p>

<p>I can view the current config with <code>kubectl config view</code> as well as directly access the stored state at <code>~/.kube/config</code>, such as:</p>

<pre><code>apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED
    server: https://api.{CLUSTER_NAME}
  name: {CLUSTER_NAME}
contexts:
- context:
    cluster: {CLUSTER_NAME}
    user: {CLUSTER_NAME}
  name: {CLUSTER_NAME}
current-context: {CLUSTER_NAME}
kind: Config
preferences: {}
users:
- name: {CLUSTER_NAME}
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
    password: REDACTED
    username: admin
- name: {CLUSTER_NAME}-basic-auth
  user:
    password: REDACTED
    username: admin
</code></pre>

<p>I need to enable other users to also administer. This <a href="https://kubernetes.io/docs/user-guide/sharing-clusters/" rel="noreferrer">user guide</a> describes how to define these on another users machine, but doesn't describe how to actually create the user's credentials within the cluster itself. How do you do this?</p>

<p>Also, is it safe to just share the <code>cluster.certificate-authority-data</code>?</p>

<p>For a full overview on Authentication, refer to the official Kubernetes docs on <a href="https://kubernetes.io/docs/admin/authentication/#openid-connect-tokens" rel="noreferrer">Authentication</a> and <a href="http://kubernetes.io/docs/admin/authorization/" rel="noreferrer">Authorization</a></p>
<p>For users, ideally you use an Identity provider for Kubernetes (OpenID Connect).</p>
<p>If you are on GKE / ACS you integrate with respective Identity and Access Management frameworks</p>
<p>If you self-host kubernetes (which is the case when you use kops), you may use <a href="https://github.com/coreos/dex#kubernetes--dex" rel="noreferrer">coreos/dex</a> to integrate with LDAP / OAuth2 identity providers - a good reference is this detailed 2 part <a href="https://thenewstack.io/single-sign-kubernetes-command-line-experience/" rel="noreferrer">SSO for Kubernetes</a> article.</p>
<p>kops (1.10+) now has built-in <a href="https://github.com/kubernetes/kops/blob/release-1.11/docs/authentication.md" rel="noreferrer">authentication support</a> which eases the integration with AWS IAM as identity provider if you're on AWS.</p>
<p>for Dex there are a few open source cli clients as follows:</p>
<ul>
<li><a href="https://github.com/Nordstrom/kubelogin" rel="noreferrer">Nordstrom/kubelogin</a></li>
<li><a href="https://github.com/pusher/k8s-auth-example" rel="noreferrer">pusher/k8s-auth-example</a></li>
</ul>
<p>If you are looking for a quick and easy (not most secure and easy to manage in the long run) way to get started, you may abuse <code>serviceaccounts</code> - with 2 options for specialised Policies to control access. (see below)</p>
<p><strong>NOTE since 1.6  Role Based Access Control is strongly recommended! this answer does not cover RBAC setup</strong></p>
<p><strong>EDIT</strong>: Great, but outdated (2017-2018), guide by Bitnami on <a href="https://docs.bitnami.com/kubernetes/how-to/configure-rbac-in-your-kubernetes-cluster/" rel="noreferrer">User setup with RBAC</a> is also available.</p>
<p>Steps to enable service account access are (depending on if your cluster configuration includes RBAC or ABAC policies, these accounts may have full Admin rights!):</p>
<p><strong>EDIT</strong>: <a href="https://gist.github.com/so0k/8fad3b1639b3d70cd841703fda67f16b" rel="noreferrer">Here is a bash script to automate Service Account creation - see below steps</a></p>
<ol>
<li><p>Create service account for user <code>Alice</code></p>
<pre><code>kubectl create sa alice
</code></pre>
</li>
<li><p>Get related secret</p>
<pre><code>secret=$(kubectl get sa alice -o json | jq -r .secrets[].name)
</code></pre>
</li>
<li><p>Get <code>ca.crt</code> from secret (using OSX <code>base64</code> with <code>-D</code> flag for decode)</p>
<pre><code>kubectl get secret $secret -o json | jq -r '.data[&quot;ca.crt&quot;]' | base64 -D &gt; ca.crt
</code></pre>
</li>
<li><p>Get service account token from secret</p>
<pre><code>user_token=$(kubectl get secret $secret -o json | jq -r '.data[&quot;token&quot;]' | base64 -D)
</code></pre>
</li>
<li><p>Get information from your kubectl config (current-context, server..)</p>
<pre><code># get current context
c=$(kubectl config current-context)

# get cluster name of context
name=$(kubectl config get-contexts $c | awk '{print $3}' | tail -n 1)

# get endpoint of current context 
endpoint=$(kubectl config view -o jsonpath=&quot;{.clusters[?(@.name == \&quot;$name\&quot;)].cluster.server}&quot;)
</code></pre>
</li>
<li><p>On a fresh machine, follow these steps (given the <code>ca.cert</code> and <code>$endpoint</code> information retrieved above:</p>
<ol>
<li><p>Install <code>kubectl</code></p>
<pre><code> brew install kubectl
</code></pre>
</li>
<li><p>Set cluster (run in directory where <code>ca.crt</code> is stored)</p>
<pre><code> kubectl config set-cluster cluster-staging \
   --embed-certs=true \
   --server=$endpoint \
   --certificate-authority=./ca.crt
</code></pre>
</li>
<li><p>Set user credentials</p>
<pre><code> kubectl config set-credentials alice-staging --token=$user_token
</code></pre>
</li>
<li><p>Define the combination of alice user with the staging cluster</p>
<pre><code> kubectl config set-context alice-staging \
   --cluster=cluster-staging \
   --user=alice-staging \
   --namespace=alice
</code></pre>
</li>
<li><p>Switch current-context to <code>alice-staging</code> for the user</p>
<pre><code> kubectl config use-context alice-staging
</code></pre>
</li>
</ol>
</li>
</ol>
<p>To control user access with policies (using <a href="https://kubernetes.io/docs/admin/authorization/abac/" rel="noreferrer">ABAC</a>), you need to create a <a href="https://kubernetes.io/docs/admin/authentication/#openid-connect-tokens" rel="noreferrer"><code>policy</code></a> file (for example):</p>
<pre><code>{
  &quot;apiVersion&quot;: &quot;abac.authorization.kubernetes.io/v1beta1&quot;,
  &quot;kind&quot;: &quot;Policy&quot;,
  &quot;spec&quot;: {
    &quot;user&quot;: &quot;system:serviceaccount:default:alice&quot;,
    &quot;namespace&quot;: &quot;default&quot;,
    &quot;resource&quot;: &quot;*&quot;,
    &quot;readonly&quot;: true
  }
}
</code></pre>
<p>Provision this <code>policy.json</code> on every master node and add <code>--authorization-mode=ABAC --authorization-policy-file=/path/to/policy.json</code> flags to API servers</p>
<p>This would allow Alice (through her service account) read only rights to all resources in default namespace only.</p>
