linkerd2/controller/identity
Tarun Pothulapati 92421d047a
core: use serviceAccountToken volume for pod authentication (#7117)
Fixes #3260 

## Summary

Currently, Linkerd uses a service Account token to validate a pod
during the `Certify` request with identity,  through which identity
is established on the proxy. This works well and good, as Kubernetes
attaches the `default` service account token of a namespace as a volume
(unless overridden with a specific service account by the user). Catch
here being that this token is aimed at the application to talk to the
kubernetes API and not specifically for Linkerd. This means that there
are [controls outside of Linkerd](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server), to manage this service token, which
users might want to use, [causing problems with Linkerd](https://github.com/linkerd/linkerd2/issues/3183)
as Linkerd might expect it to be present.

To have a more granular control over the token, and not rely on the
service token that can be managed externally, [Bound Service Tokens](https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/1205-bound-service-account-tokens)
can be used to generate tokens that are specifically for Linkerd,
that are bound to a specific pod, along with an expiry.

## Background on Bounded Service Tokens 

This feature has been GA’ed in Kubernetes 1.20, and is enabled by default
in most cloud provider distributions. Using this feature, Kubernetes can
be asked to issue specific tokens for linkerd usage (through audience bound
configuration), with a specific expiry time (as the validation happens every
24 hours when establishing identity, we can follow the same), bounded to
a specific pod (meaning verification fails if the pod object isn’t available).

Because of all these bounds, and not being able to use this token for
anything else, This feels like the right thing to rely on to validate
a pod to issue a certificate.

### Pod Identity Name

We still use the same service account name as the pod identity
(used with metrics, etc) as these tokens are all generated from the
same base service account attached to the pod (could be defualt, or
the user overriden one). This can be verified by looking at the `user`
field in the `TokenReview` response.

<details>

<summary>Sample TokenReview response</summary>

Here, The new token was created for the vault audience for a pod which
had a serviceAccount token volume projection and was using the `mine`
serviceAccount in the default namespace.

```json
  "kind": "TokenReview",
  "apiVersion": "authentication.k8s.io/v1",
  "metadata": {
    "creationTimestamp": null,
    "managedFields": [
      {
        "manager": "curl",
        "operation": "Update",
        "apiVersion": "authentication.k8s.io/v1",
        "time": "2021-10-19T19:21:40Z",
        "fieldsType": "FieldsV1",
        "fieldsV1": {"f:spec":{"f:audiences":{},"f:token":{}}}
      }
    ]
  },
  "spec": {
    "token": "....",
    "audiences": [
      "vault"
    ]
  },
  "status": {
    "authenticated": true,
    "user": {
      "username": "system:serviceaccount:default:mine",
      "uid": "889a81bd-e31c-4423-b542-98ddca89bfd9",
      "groups": [
        "system:serviceaccounts",
        "system:serviceaccounts:default",
        "system:authenticated"
      ],
      "extra": {
        "authentication.kubernetes.io/pod-name": [
  "nginx"
],
        "authentication.kubernetes.io/pod-uid": [
  "ebf36f80-40ee-48ee-a75b-96dcc21466a6"
]
      }
    },
    "audiences": [
      "vault"
    ]
  }

```

</details>


## Changes

- Update `proxy-injector` and install scripts to include the new
  projected Volume and VolumeMount.
- Update the `identity` pod to validate the token with the linkerd
  audience key.
- Added `identity.serviceAccountTokenProjection`  to disable this
 feature.
- Updated err'ing logic with `autoMountServiceAccount: false`
 to fail only when this feature is disabled.
Signed-off-by: Tarun Pothulapati <tarunpothulapati@outlook.com>
2021-11-03 02:03:39 +05:30
..
domain.go Introduce the Identity controller implementation (#2521) 2019-03-19 13:58:45 -07:00
validator.go core: use serviceAccountToken volume for pod authentication (#7117) 2021-11-03 02:03:39 +05:30