> For the complete documentation index, see [llms.txt](https://kubernetes.feisky.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kubernetes.feisky.xyz/en/extension/auth/authentication.md).

# Authentication

When Transport Layer Security (TLS) is enabled, all requests must be authenticated first. Kubernetes supports a variety of authentication mechanisms and allows multiple authentication plugins to be activated at the same time. The system counts a request as authenticated as long as one of the plugins authenticates it. If authentication succeeds, the user's `username` is passed to the authorization module for further verification. However, if authentication fails, the request returns HTTP 401 (Unauthorized).

> **Kubernetes Doesn't Manage Users Directly**
>
> Although Kubernetes uses `user` and `group` for authentication and authorization, it doesn't directly manage the users. It can't create a `user` object, nor does it store users.

Currently, Kubernetes supports the following authentication plugins:

* X509 certificates
* Static Token files
* Bootstrap Tokens
* Static Password files
* Service Accounts
* OpenID
* Webhook
* Authentication Proxy
* OpenStack Keystone Password

## X509 Certificates

To employ X509 client certificates, configure `--client-ca-file=SOMEFILE` when launching your API Server. During certificate authentication, its Common Name (CN) field is used as the username, while the Organization (O) field serves as the group name.

To create a client certificate, follow these steps:

```bash
# Create private key
openssl genrsa -out username.key 2048
# Create CSR (Certificate Signing Request)
openssl req -new -key username.key -out username.csr -subj "/CN=username/O=group"
# Create certificate from CSR using the cluster authority
openssl x509 -req -in username.csr -CA $CA_LOCATION/ca.crt -CAkey $CA_LOCATION/ca.key -CAcreateserial -out username.crt -days 500
```

Then, you can use `username.key` and `username.crt` to access the cluster:

```bash
# Configure the cluster
kubectl config set-cluster my-cluster --certificate-authority=ca.pem --embed-certs=true --server=https://<APISERVER_IP>:6443
# Configure credentials
kubectl config set-credentials username --client-certificate=username.crt --client-key=username.key --embed-certs=true
# Configure context
kubectl config set-context username --cluster=my-cluster --user=username
# Configure RBAC if enabled
# Finally, switch to the new context
kubectl config use-context username
```

## Static Token Files

To use static token file authentication, configure `--token-auth-file=SOMEFILE` when launching your API Server. This file should be in csv (Comma Separated Values) format, each line should have at least three columns, `token,username,user id`. You can optionally add group name columns after the required columns:

```
token,user,uid,"group1,group2,group3"
```

While using token authentication, the client must include a Bearer Authorization header in the request:

```
Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269
```

## Bootstrap Tokens

Bootstrap tokens are dynamically generated and stored in the `kube-system` namespace's Secret. They're used to deploy new Kubernetes clusters.

To use bootstrap tokens, configure `--experimental-bootstrap-token-auth` when starting the API Server. Also, enable TokenCleaner in the Controller Manager with `--controllers=*,tokencleaner,bootstrapsigner`.

When deploying Kubernetes with `kubeadm`, `kubeadm` automatically creates a default token, which can be checked with the `kubeadm token list` command.

## Static Password Files

Configure `--basic-auth-file=SOMEFILE` when launching the API Server. The file should be in csv format, each line should contain at least three columns `password, user, uid`. You can optionally add group name columns:

```
password,user,uid,"group1,group2,group3"
```

During password authentication, the client includes a Basic Authorization header in the request:

```
Authorization: Basic BASE64ENCODED(USER:PASSWORD)
```

## Service Accounts

A ServiceAccount is automatically generated by Kubernetes and mounted to the container's `/var/run/secrets/kubernetes.io/serviceaccount` directory.

During authentication, a ServiceAccount's username format is `system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT)`, and it belongs to two groups: `system:serviceaccounts` and `system:serviceaccounts:(NAMESPACE)`.

## OpenID

OpenID provides an OAuth2 authentication mechanism and is the preferred authentication method for many cloud service providers, such as Google Cloud Engine (GCE), Azure, and others.

![OpenID\_1](/files/gcxCLcU6j1dPo1J9nhWQ)

To use OpenID authentication, the API Server must be configured with:

* `--oidc-issuer-url` (for example, `https://accounts.google.com`)
* `--oidc-client-id` (for example, `kubernetes`)
* `--oidc-username-claim` (for example, `sub`)
* `--oidc-groups-claim` (for example, `groups`)
* `--oidc-ca-file` (for example, `/etc/kubernetes/ssl/kc-ca.pem`)

## Webhook

For the API Server to configure:

```bash
# To configure how to access the webhook server
--authentication-token-webhook-config-file
# Default is 2 minutes
--authentication-token-webhook-cache-ttl
```

The configuration file format is:

```yaml
# 'clusters' refers to the remote service.
clusters:
  - name: name-of-remote-authn-service
    cluster:
      # CA for verifying the remote service.
      certificate-authority: /path/to/ca.pem
      # URL of remote service to query. Must use 'https'.
      server: https://authn.example.com/authenticate

# 'users' refers to the API server's webhook configuration.
users:
  - name: name-of-api-server
    user:
      # Cert for the webhook plugin to use
      client-certificate: /path/to/cert.pem
      # Key matching the certificate
      client-key: /path/to/key.pem

# kubeconfig files require a context. Provide one for the API server.
current-context: webhook
contexts:
- context:
    cluster: name-of-remote-authn-service
    user: name-of-api-sever
  name: webhook
```

The request format sent from Kubernetes to the webhook server is:

```javascript
{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "spec": {
    "token": "(BEARERTOKEN)"
  }
}
```

Example: [kubernetes-github-authn](https://github.com/oursky/kubernetes-github-authn) offers an implementation of GitHub authentication based on Webhook.

## Authentication Proxy

For the API Server, configuring is required:

```bash
--requestheader-username-headers=X-Remote-User
--requestheader-group-headers=X-Remote-Group
--requestheader-extra-headers-prefix=X-Remote-Extra-
# To guard against header spoofing, the certificate is mandatory
--requestheader-client-ca-file
# Set the allowed CN list. Optional.
--requestheader-allowed-names
```

## Openstack Keystone Password

When starting the API Server, the `--experimental-keystone-url=<AuthURL>` must be specified. For https, the `--experimental-keystone-ca-file=SOMEFILE` needs to be set.

> **Doesn't Support Keystone Version 3**
>
> Currently, only keystone v2.0 is supported. Version 3 is not supported (cannot pass domain).

## Anonymous Requests

If you use any authentication mode other than 'AlwaysAllow', anonymous requests are activated by default. You can disable anonymous requests by using `--anonymous-auth=false`.

An anonymous request's username format is `system:anonymous`, and the group is `system:unauthenticated`.

## Credential Plugin

Beginning from v1.11, Kubernetes supports the Credential Plugin (Beta), which calls an external plugin to acquire user credentials. It's a type of client authentication plugin that supports authentication protocols not natively supported in Kubernetes, such as LDAP, OAuth2, SAML, and others. It is often used in conjunction with [Webhook](#webhook).

Credential Plugin setup can be done in the `kubectl` setup file, such as:

```yaml
apiVersion: v1
kind: Config
users:
- name: my-user
  user:
    exec:
      # Command to execute. Required.
      command: "example-client-go-exec-plugin"
      # API version to use when decoding the ExecCredentials resource. Required.
      # 
      # The API version returned by the plugin must match the version listed here.
      #
      # To integrate with tools that support multiple versions (such as client.authentication.k8s.io/v1alpha1),
      # set an environment variable or pass an argument to the tool that indicates which version the exec plugin expects.
      apiVersion: "client.authentication.k8s.io/v1beta1"
      # Environment variables to set when executing the plugin. Optional.
      env:
      - name: "FOO"
        value: "bar"
      # Arguments to pass when executing the plugin. Optional.
      args:
      - "arg1"
      - "arg2"
clusters:
- name: my-cluster
  cluster:
    server: "https://172.17.4.100:6443"
    certificate-authority: "/etc/kubernetes/ca.pem"
contexts:
- name: my-cluster
  context:
    cluster: my-cluster
    user: my-user
current-context: my-cluster
```

To learn more about plugin development and usage, refer to [kubernetes/client-go](https://github.com/kubernetes/client-go/tree/master/plugin/pkg/client/auth).

## Open Source Tools

The following open-source tools can simplify your authentication and authorization configurations:

* [Keycloak](https://www.keycloak.org/)
* [coreos/dex](https://github.com/coreos/dex)
* [heptio/authenticator](https://github.com/heptio/authenticator)
* [hashicorp/vault-plugin-auth-kubernetes](https://github.com/hashicorp/vault-plugin-auth-kubernetes)
* [appscode/guard](https://github.com/appscode/guard)
* [cyberark/conjur](https://github.com/cyberark/conjur)
* [liggitt/audit2rbac](https://github.com/liggitt/audit2rbac)
* [reactiveops/rbac-manager](https://github.com/reactiveops/rbac-manager)
* [jtblin/kube2iam](https://github.com/jtblin/kube2iam)

## References

* <https://kubernetes-security.info>
* [Protect Kubernetes External Endpoints with OAuth2 Proxy](https://akomljen.com/protect-kubernetes-external-endpoints-with-oauth2-proxy/) by Alen Komljen
* [Single Sign-On for Internal Apps in Kubernetes using Google Oauth / SSO](https://medium.com/@while1eq1/single-sign-on-for-internal-apps-in-kubernetes-using-google-oauth-sso-2386a34bc433) by William Broach
* [Single Sign-On for Kubernetes: An Introduction](https://thenewstack.io/kubernetes-single-sign-one-less-identity/) by Joel Speed
* [Let’s Encrypt, OAuth 2, and Kubernetes Ingress](https://eng.fromatob.com/post/2017/02/lets-encrypt-oauth-2-and-kubernetes-ingress/) by Ian Chiles
* [Comparing Kubernetes Authentication Methods](https://medium.com/@etienne_24233/comparing-kubernetes-authentication-methods-6f538d834ca7) by Etienne Dilocker
* [K8s auth proxy example](http://uptoknow.blogspot.com/2017/06/kubernetes-authentication-proxy-example.html)
* [K8s authentication with Conjur](https://blog.conjur.org/kubernetes-authentication)
* [Effective RBAC](https://www.youtube.com/watch?v=Nw1ymxcLIDI) by Jordan Liggitt
* [Configure RBAC In Your Kubernetes Cluster](https://docs.bitnami.com/kubernetes/how-to/configure-rbac-in-your-kubernetes-cluster/) via Bitnami
* [Using RBAC, Generally Available in Kubernetes v1.8](https://kubernetes.io/blog/2017/10/using-rbac-generally-available-18/) by Eric Chiang
