# Authentication, Authorization and Admission Control

## Authentication

* Kubernetes does not have an object called user, nor does it store usernames or other related details in its object store.
* However, even without that, Kubernetes can use usernames for the Authentication phase of the API access control, and to request logging as well.
* Kubernetes supports two kinds of users:
  * Normal Users
    * They are managed outside of the Kubernetes cluster via independent services like `User/Client Certificates`, a file listing `usernames/passwords`, `Google accounts`, etc.
  * Service Accounts
    * Service Accounts allow in-cluster processes to communicate with the API server to perform various operations.
    * Most of the Service Accounts are created automatically via the API server, but they can also be created manually.
    * The Service Accounts are tied to a particular Namespace and mount the respective credentials to communicate with the API server as Secrets.
* Kubernetes can also support anonymous requests, along with requests from Normal Users and Service Accounts.
  * User impersonation is also supported allowing a user to act as another user, a helpful feature for administrators when troubleshooting authorization policies.

### Authentication Modules

* **X509 Client Certificates**
  * To enable client certificate authentication, we need to reference a file containing one or more certificate authorities by passing the `--client-ca-file=SOMEFILE` option to the API server.
  * The certificate authorities mentioned in the file would validate the client certificates presented by users to the API server.
* **Static Token File**
  * We can pass a file containing pre-defined bearer tokens with the `--token-auth-file=SOMEFILE` option to the API server.
  * Currently, these tokens would last indefinitely, and they cannot be changed without restarting the API server.
* **Bootstrap Tokens**
  * Tokens used for bootstrapping new Kubernetes clusters.
* **Service Account Tokens**
  * Automatically enabled authenticators that use signed bearer tokens to verify requests. These tokens get attached to Pods using the Service Account Admission Controller, which allows in-cluster processes to talk to the API server.
* **OpenID Connect Tokens**
  * OpenID Connect helps us connect with `OAuth2` providers, such as Microsoft Entra ID _(previously known as Azure Active Directory)_, Salesforce, and Google, to offload the authentication to external services.
* **Webhook Token Authentication**
  * With Webhook-based authentication, verification of bearer tokens can be offloaded to a remote service.
* **Authenticating Proxy**
  * Allows for the programming of additional authentication logic.
* We can enable multiple authenticators, and the first module to successfully authenticate the request short-circuits the evaluation.
* To ensure successful user authentication, we should enable at least two methods: the service account tokens authenticator and one of the user authenticators.

## Authorization

* After a successful authentication, users can send the API requests to perform different operations.
* Here, these API requests get authorized by Kubernetes using various authorization modules that allow or deny the requests.
* Some of the API request attributes that are reviewed by Kubernetes include user, group, Resource, Namespace, or API group, to name a few.
  * These attributes are evaluated against policies. If the evaluation is successful, then the request is allowed, otherwise it is denied.
* Similar to the Authentication step, Authorization has multiple modules, or authorizers. More than one module can be configured for one Kubernetes cluster, and each module is checked in sequence. If any authorizer approves or denies a request, then that decision is returned immediately.

### Node Authorization

* Node authorization is a special-purpose authorization mode which specifically authorizes API requests made by kubelets. It authorizes the kubelet's read operations for services, endpoints, or nodes, and writes operations for nodes, pods, and events.

### Types of Authorization

#### Attribute-Based Access Control (ABAC)

* With the ABAC authorizer, Kubernetes grants access to API requests, which combine policies with attributes.
* In the following example, user bob can only read Pods in the Namespace `lfs158`.

```json
{
    "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
    "kind": "Policy",
    "spec": {
        "user": "bob",
        "namespace": "lfs158",
        "resource": "pods",
        "readonly": true
    }
}
```

* To enable ABAC mode, we start the API server with the `--authorization-mode=ABAC` option, while specifying the authorization policy with `--authorization-policy-file=PolicyFile.json`.

#### Role-Based Access Control (RBAC)

* In general, with RBAC we regulate the access to resources based on the `Roles` of individual users.
* In Kubernetes, multiple Roles can be attached to subjects like `users`, `service accounts`, etc.
* While creating the `Roles`, we restrict resource access by specific operations, such as `create`, `get`, `update`, `patch`, etc, these operations are referred to as verbs.
* To enable the RBAC mode, we start the API server with the `--authorization-mode=RBAC` option, allowing us to dynamically configure policies.
* In RBAC, we can create two kinds of Roles:
  * `Role`
    * A Role grants access to resources within a specific Namespace.
  * `ClusterRole`
    * A ClusterRole grants the same permissions as Role does, but its scope is cluster-wide.
  * Examples
    *   Pod reader role yaml

        ```yaml
            apiVersion: rbac.authorization.k8s.io/v1
            kind: Role
            metadata:
                namespace: lfs158
                name: pod-reader
            rules:
                - apiGroups: [""] # "" indicates the core API group
                resources: ["pods"]
                verbs: ["get", "watch", "list"]
        ```
    *   Cluster Admin Role yaml

        ```yaml
            apiVersion: rbac.authorization.k8s.io/v1
            kind: ClusterRole
            metadata:
                name: cluster-admin
            rules:
            - apiGroups:
                - '*' # All API groups
                resources:
                - '*' # All resources
                verbs:
                - '*' # All operations
            - nonResourceURLs:
                - '*' # All non resource URLs, such as "/healthz"
                verbs:
                - '*' # All operations
        ```

### Role Binding

* Once the role is created, we can bind it to users with a RoleBinding object. There are two kinds of RoleBindings.

#### RoleBinding

* It allows us to bind users to the same namespace as a Role.
*   Also referred to a ClusterRole in RoleBinding, which would grant permissions to Namespace resources defined in the ClusterRole within the RoleBinding’s Namespace.

    ```yaml
        apiVersion: rbac.authorization.k8s.io/v1
        kind: RoleBinding
        metadata:
        name: pod-read-access
        namespace: lfs158
        subjects:
        - kind: User
        name: bob
        apiGroup: rbac.authorization.k8s.io
        roleRef:
        kind: Role
        name: pod-reader
        apiGroup: rbac.authorization.k8s.io
    ```
* The manifest defines a bind between the `pod-reader` Role and user `bob`, to restrict the user to only read the Pods of the `lfs158` Namespace.

#### ClusterRoleBinding

*   It allows us to grant access to resources at a cluster-level and to all Namespaces.

    ```yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: cluster-admin
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: Group
      name: system:admins
    ```
* The manifest defines a bind between the cluster-admin ClusterRole and all users of the group system:admins.

### Webhook

* In Webhook mode, Kubernetes can request authorization decisions to be made by third-party services, which would return true for successful authorization, and false for failure.
* In order to enable the Webhook authorizer, we need to start the API server with the `--authorization-webhook-config-file=SOME_FILENAME` option, where `SOME_FILENAME` is the configuration of the remote authorization service.

## Admission Control

* They are used to specify granular access control policies, which include allowing privileged containers, checking on resource quota etc.
* We force these policies using different admission controllers, like `LimitRanger`, `ResourceQuota`, `DefaultStorageClass`, `AlwaysPullImages`, etc.
* They come into effect only after API requests are authenticated and authorized. Admission controllers fall under two categories
  * Validating
  * Mutating
  * But there are controllers that are both validating and mutating. The mutating controllers can modify the requested objects.
* To use admission controls, we must start the Kubernetes API server with the `--enable-admission-plugins`, which takes a comma-delimited, ordered list of controller names like `--enable-admission-plugins=NamespaceLifecycle,ResourceQuota,PodSecurity,DefaultStorageClass`.
* Kubernetes has some admission controllers enabled by default.
  * Kubernetes admission control can also be implemented though custom plugins, for a dynamic admission control method. These plugins are developed as extensions and run as admission webhooks.

## Reference

* [Admission Controllers](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#what-does-each-admission-controller-do)
