# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kubernetes.feisky.xyz/en/extension/auth/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
