linkerd2/cli/cmd
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
..
testdata core: use serviceAccountToken volume for pod authentication (#7117) 2021-11-03 02:03:39 +05:30
alpha.go Remove SMI-Metrics charts and commands (#4843) 2020-08-24 14:35:33 -07:00
authz.go Add linkerd viz authz command (#6875) 2021-09-21 09:36:05 -07:00
check.go Do not install PSP resources by default (#6558) 2021-07-29 15:37:54 -05:00
check_test.go Fix hint anchors for core health checks (#6023) 2021-04-13 09:56:23 -05:00
completion.go Add support for server resource aware completion (#6091) 2021-05-18 09:59:59 -04:00
completion_test.go Bump proxy-init to 1.2.0 (#3397) 2019-09-09 09:06:14 -07:00
controller-metrics.go cli: reorganise diagnostics subcommand (#5205) 2021-02-25 12:53:47 +05:30
diagnostics.go cli: Remove the install-sp command (#6118) 2021-05-24 13:31:07 -07:00
doc.go Update proxy annotations docs (#6051) 2021-04-22 15:46:02 -05:00
endpoints.go add resource aware completion for core linkerd cmd (#6217) 2021-06-07 10:45:19 -05:00
endpoints_test.go Remove the `linkerd-controller` pod (#6039) 2021-04-19 09:57:45 -05:00
identity.go Refactor edges command (#6574) 2021-08-05 11:01:03 -07:00
inject.go core: use serviceAccountToken volume for pod authentication (#7117) 2021-11-03 02:03:39 +05:30
inject_test.go core: use serviceAccountToken volume for pod authentication (#7117) 2021-11-03 02:03:39 +05:30
inject_util.go Update `inject` to throw an error while injecting non-compliant pods (#4346) 2020-06-24 14:07:05 -05:00
install-cni-plugin.go Introduce LINKERD_DOCKER_REGISTRY and flexibilize CI workflows (#6782) 2021-09-01 13:39:05 -05:00
install-cni-plugin_test.go docker: Access container images via cr.l5d.io (#5756) 2021-02-17 14:31:54 -08:00
install.go Add policy CRDs (#6486) 2021-08-04 09:28:26 -07:00
install_cni_helm_test.go Removed "do-not-edit" entries from values.yaml files (#5758) 2021-02-19 09:17:45 -05:00
install_helm_test.go feat: remove cert expiry date in helm charts (#7056) 2021-10-08 11:32:05 -05:00
install_test.go core: use serviceAccountToken volume for pod authentication (#7117) 2021-11-03 02:03:39 +05:30
main_test.go viz: add render golden tests (#5433) 2021-01-12 11:59:16 +05:30
metrics.go Add linkerd viz authz command (#6875) 2021-09-21 09:36:05 -07:00
metrics_diagnostics_util.go Linkerd CLI command to get control plane diagnostics (#4050) 2020-02-24 09:09:54 -08:00
metrics_diagnostics_util_test.go Bump k8s client-go to v0.19.2 (#5002) 2020-09-28 12:45:18 -05:00
options.go feat: remove cert expiry date in helm charts (#7056) 2021-10-08 11:32:05 -05:00
profile.go values: removal of .global field (#5699) 2021-02-11 23:38:34 +05:30
profile_test.go Bump helm.sh/helm/v3 from 3.4.1 to 3.6.1 (#6286) 2021-06-18 09:34:29 -06:00
range_slice.go Enable mixed configuration of skip-[inbound|outbound]-ports (#3766) 2019-12-20 09:32:13 -05:00
range_slice_test.go Enable mixed configuration of skip-[inbound|outbound]-ports (#3766) 2019-12-20 09:32:13 -05:00
repair.go remove some hard-coded and duplicate constants (#6675) 2021-08-16 08:47:37 -04:00
root.go Create linkerd authz command (#6831) 2021-09-10 16:19:49 -07:00
test_helper.go Refactor upgrade tests to remove use of golden files (#4860) 2020-08-11 09:22:29 -07:00
uninject.go CLI: add `--opaque-ports` flag to `inject` (#5851) 2021-03-02 08:59:09 -08:00
uninject_test.go viz: add render golden tests (#5433) 2021-01-12 11:59:16 +05:30
uninstall.go Add support for legacy names in extension uninstall (#6226) 2021-06-08 20:18:52 +05:30
upgrade.go Update CLI upgrade help docs (#6916) 2021-09-23 11:59:13 -05:00
upgrade_legacy.go feat: remove cert expiry date in helm charts (#7056) 2021-10-08 11:32:05 -05:00
upgrade_test.go feat: remove cert expiry date in helm charts (#7056) 2021-10-08 11:32:05 -05:00
version.go Removed `Version` API from the public-api (#6000) 2021-04-16 11:23:55 -05:00