sigs.k8s.io/cluster-api@v1.7.1/docs/proposals/20210222-kubelet-authentication.md (about)

     1  ---
     2  
     3  title: Cluster API Kubelet Authentication
     4  authors:
     5    - "@randomvariable"
     6    - "@yastij"
     7  reviewers:
     8    - "@ashish-amarnath"
     9    - "@alexander-demichev"
    10    - "@arvinderpal"
    11    - "@cecilerobertmichon"
    12    - "@elmiko"
    13    - "@enxebre"
    14    - "@fabriziopandini"
    15    - "@joelspeed"
    16    - "@jpeach"
    17    - "@kfox1111"
    18    - "@neolit123"
    19    - "@sbueringer"
    20    - "@sftim"
    21    - "@vincepri"
    22  creation-date: 2021-02-22
    23  last-updated: 2021-04-29
    24  status: implementable
    25  replaces:
    26  superseded-by:
    27  
    28  ---
    29  
    30  # Cluster API Kubelet Authentication
    31  
    32  
    33  ## Table of Contents
    34  
    35  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
    36  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
    37  
    38  - [Glossary](#glossary)
    39  - [Summary](#summary)
    40  - [Motivation](#motivation)
    41    - [Goals](#goals)
    42    - [Non-Goals/Future Work](#non-goalsfuture-work)
    43  - [Proposal](#proposal)
    44    - [User Stories](#user-stories)
    45      - [Story 1: Machine Attestation](#story-1-machine-attestation)
    46      - [Story 2: MachinePool race conditions](#story-2-machinepool-race-conditions)
    47    - [Requirements](#requirements)
    48    - [Implementation Details/Notes/Constraints](#implementation-detailsnotesconstraints)
    49      - [New Components](#new-components)
    50      - [Kubelet authentication plugin](#kubelet-authentication-plugin)
    51      - [Node Attestation](#node-attestation)
    52      - [CSR format used by kubelet-authenticator](#csr-format-used-by-kubelet-authenticator)
    53        - [OIDs](#oids)
    54      - [CSR PEM Blocks](#csr-pem-blocks)
    55      - [Attestation data](#attestation-data)
    56      - [Core Specification](#core-specification)
    57      - [Provider Specification](#provider-specification)
    58        - [All providers](#all-providers)
    59        - [Insecure providers](#insecure-providers)
    60        - [Secure providers](#secure-providers)
    61        - [TPM based providers](#tpm-based-providers)
    62      - [Kubeadm](#kubeadm)
    63      - [Changes to the Cluster and core Cluster API controller](#changes-to-the-cluster-and-core-cluster-api-controller)
    64      - [Changes to KubeadmControlPlane resources and controller](#changes-to-kubeadmcontrolplane-resources-and-controller)
    65      - [Changes to Cluster API Bootstrap Provider Kubeadm](#changes-to-cluster-api-bootstrap-provider-kubeadm)
    66        - [Changes to token rotation](#changes-to-token-rotation)
    67      - [Kubelet authenticator flow](#kubelet-authenticator-flow)
    68        - [Client CSR flow](#client-csr-flow)
    69        - [Serving CSR handling](#serving-csr-handling)
    70    - [Risks and Mitigations](#risks-and-mitigations)
    71  - [Alternatives](#alternatives)
    72      - [Implement within the cloud providers instead of Cluster API](#implement-within-the-cloud-providers-instead-of-cluster-api)
    73      - [Implement as authentication webhook, as per aws-iam-authenticator (Amazon EKS)](#implement-as-authentication-webhook-as-per-aws-iam-authenticator-amazon-eks)
    74      - [SPIRE/SPIFFE](#spirespiffe)
    75  - [Upgrade Strategy](#upgrade-strategy)
    76  - [Additional Details](#additional-details)
    77    - [Test Plan [optional]](#test-plan-optional)
    78    - [Graduation Criteria [optional]](#graduation-criteria-optional)
    79      - [Graduation to beta](#graduation-to-beta)
    80      - [Graduation to GA](#graduation-to-ga)
    81    - [Version Skew Strategy](#version-skew-strategy)
    82  - [Implementation History](#implementation-history)
    83  
    84  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
    85  
    86  ## Glossary
    87  
    88  
    89  - **OID:** Object Identifier defined by the International Telecommunications Union and used in PKI
    90    to identify attributes on certificates.
    91  
    92  - **PKI:** Public Key Infrastructure
    93  
    94  - **TPM:** Trusted Platform Module (TPM) is a specification defined by the Trusted Computing Group
    95    (TCG) that allows hosts to attest to their identity via PKI and a secure crypto-processor which
    96    may either be a separate chip, built into the CPU or a virtual device provided by the hypervisor.
    97  
    98  - **Trust on first use:** Often abbreviated to TOFU is an authentication convention that a provided
    99    credential is only trusted from one endpoint which is recorded, and if presented again from a
   100    different endpoint it is untrusted. See https://en.wikipedia.org/wiki/Trust_on_first_use for more
   101    information.
   102  
   103  
   104  ## Summary
   105  
   106  This proposal outlines a method to secure node registration within Cluster API, to solve 2 primary
   107  problems:
   108  
   109  - Solve a class of attacks involving node impersonation allowing an attacker to access secrets and
   110    volumes they shouldn’t by using hardware attestation of node identity.
   111  - Reduce kubeadm token reuse in MachinePools where the cloud provider does not support continuous
   112    update of the bootstrap userdata without creating new cloud provider specific MachinePool
   113    resources (e.g. AWS Launch Configurations).
   114  
   115  This node attestation mechanism will be optional in the initial implementation, and can potentially
   116  be used independently of Cluster API.
   117  
   118  ## Motivation
   119  
   120  Cluster API default core components are largely reliant on kubeadm for cluster bootstrapping and
   121  node registration. Kubeadm is a platform-agnostic command line tool designed to assist users to
   122  bootstrap Kubernetes clusters, and is used as a building block in Cluster API. Because kubeadm is
   123  platform-independent and is intended to provide an “easy path” to cluster bootstrapping,  there are
   124  a number of inherent design decisions that limit the overall security of the provisioned cluster:
   125  
   126  - Kubeadm uses TLS bootstrapping for node registration, however the default workflow used by Cluster
   127    API uses bootstrap token which allow registration as arbitrary node names.
   128    - When used in this mode, Kubeadm essentially does “client-side validation” to prevent node
   129      hijacking, but this does not mean the token cannot be reused by an attacker within the lifetime
   130      of the token to perform a hijack. By hijack, the token could be used to auto-approve a CSR
   131      for an existing node, and in particular a control plane node such that it then has access to
   132      workloads and secrets intended only for control plane instances.
   133    - Cluster API cannot scope a token down to a specific node, because neither bootstrap providers,
   134      nor most infrastructure providers know the identity of the node ahead of time.
   135  
   136  ### Goals
   137  
   138  - Provide a bootstrap mechanism that assures secure node registration
   139  - To provide a node registration mechanism that is independent of kubeadm
   140  - Ensure that this can work with any infrastructure provider
   141  
   142  
   143  ### Non-Goals/Future Work
   144  
   145  - To change assumptions around management cluster to workload cluster connectivity
   146  - Solve the protection of initial cluster bootstrap secrets for the control plane nodes
   147  - To be a mandatory requirement of using Cluster API
   148  - To implement or enable hardware-backed encryption of traffic between worker nodes and the control
   149    plane components.
   150  
   151  ## Proposal
   152  
   153  ### User Stories
   154  
   155  #### Story 1: Machine Attestation
   156  
   157  A cluster operator has been asked to ensure compliance with [NIST SP 800-190 Application Container
   158  Security][nist-sp-800-190] Guide. Hardware countermeasure 4.6 suggests that container platforms
   159  should make use of trusted computing. In a Kubernetes context, this would mean providing hardware
   160  node attestation wherever possible.
   161  
   162  #### Story 2: MachinePool race conditions
   163  
   164  A cluster operator has set up a MachinePool in either AWS or Azure, and wants the MachinePool to be
   165  reliable. The current behaviour of Cluster API Bootstrap Provider Kubeadm (CABPK) is such that
   166  bootstrap tokens are rotated at set intervals, and infrastructure providers must update their
   167  MachinePool implementations with the new secret data.
   168  
   169  This has led to either: implementation specific hacks to ensure the token gets updated, and minor
   170  race conditions where the infrastructure machine pool implementation does not have the new token
   171  inserted and attempts to bootstrap the machine with stale bearer tokens.
   172  
   173  ### Requirements
   174  
   175  The node bootstrapper MUST be able to attest the identity of the machine against a chain of trust
   176  provided by the hardware or cloud provider.
   177  
   178  
   179  ### Implementation Details/Notes/Constraints
   180  
   181  #### New Components
   182  
   183  * **node-attestation-controller**
   184    * **Code Location**: Part of Cluster API repository, under bootstrap/node/attestation/controller, and
   185      imported by Cluster API infra providers for implementation.
   186    * **Release Artifact**: Embedded controller within infrastructure providers.
   187    * **Description**: A controller to verify and sign the CSR. This would be typically an importable
   188    controller where the infrastructure provider implements the interface with specific code for CSR
   189    approval and start the controller as part of its main.go or through an independent binary.
   190  
   191  * **kubelet-authenticator**
   192    * **Code Location**: Part of Cluster API repository, under bootstrap/node/attestation/authenticator
   193      and imported by Cluster API infra providers for implementation.
   194  generic challenge-response implementation will be included for providers / bare metal without an
   195  attestation mechanism. This controller runs as part of the Cluster API components in the management
   196  cluster
   197    * **Release Artifact**: Binary for each implementing infrastructure provider called `kubelet-authenticator-<provider>`
   198    * **Description**: A controller to verify and sign the CSR. This would be typically an importable
   199    controller where the infrastructure provider implements the interface with specific code for CSR
   200    approval and start the controller as part of its main.go or through an independent binary.
   201  
   202  * **kubelet-authenticator-null**
   203    * **Code Location**: Part of CLuster API Provider, under bootstrap/node/attestation/null
   204    * **Release Artifact**: None. Used only for testing.
   205    * **Description**: A "rubber-stamp" attestor that will validate all CSRs. We will not want to release
   206      this as an artifact to prevent it being accidentally used.
   207  
   208  #### Kubelet authentication plugin
   209  
   210  We propose a kubelet authentication plugin to be present on the instances, (the
   211  kubelet-authenticator CLI will be baked into the machine images through image-builder), which will
   212  be responsible for node registration, as well as certificate rotation. The agent will be made up of
   213  two parts:
   214  - A common library vendored from Cluster API which includes the following functionality:
   215    - Certificate filesystem locking
   216    - Checking existing certificate validity
   217    - Certificate signing request generation for kubelet client certificates
   218    - Submission of CSRs to the API server and waiting for approval
   219  - A provider specific implementation for node attestation
   220    - A provider will need to implement the generation of the attestation to be included in the CSR
   221      and the retrieval of the provider ID to be stored in an X.509 extension attribute.
   222    - A provider will need to implement checks to verify the SAN attributes of serving certificates.
   223  
   224  The behaviour of the authentication plugin will be as follows:
   225  
   226  
   227  #### Node Attestation
   228  
   229  As for the node-attestation-controller, the following interface needs to be implemented by the
   230  infrastructure providers:
   231  ```go
   232  type ClusterAPISigner interface {
   233       VerifyClientAttestationData (csr *certificatesv1beta1.CertificateSigningRequest) err
   234       VerifyServingAttestationData (csr *certificatesv1beta1.CertificateSigningRequest) err
   235       MachineName (csr *certificatesv1beta1.CertificateSigningRequest) (string, error)
   236  }
   237  ```
   238  
   239  This enables infrastructure providers to perform infrastructure-specific validation of node
   240  attestations (TPM, appended tags by the provider, etc.)
   241  
   242  Cluster API is responsible for partially verifying node identity with the following conditions:
   243  
   244  - A corresponding machine object exist for the CSR's `.spec.Username` (`system:nodes:<nodename>`)
   245    (providing the value is deferred to infrastructure provider)
   246  - The Machine must have conditions BootstrapReady.
   247  - The Kubernetes CSR spec has the needed groups
   248  - The Kubernetes CSR spec is limited to needed usages (e.g. client auth)
   249  - The Kubernetes CSR spec is limited to needed extensions (e.g. no CA extension)
   250  - Parse the CSR and verify that the CN is the same as .spec.username
   251  - Parse the CSR and verify that the Organization is the same as .spec.Groups
   252  - Parse the CSR and ensure that no SANs are appended for kubelet client certificates
   253  
   254  #### CSR format used by kubelet-authenticator
   255  We propose the introduction of X.509 extension attributes based
   256  on those reserved for the Kubernetes GCP cloud provider within Google’s organization ID allocation.
   257  
   258  We will request via SIG Architecture or CNCF to apply for an [IANA OID registration
   259  block][iana-issue] for the Kubernetes project.
   260  
   261  ##### OIDs
   262  
   263  * **OID Suffix**: 2.1.21
   264  * **Name**: KubernetesNodeProviderIdentifierOID
   265  * **Description**: An identifier for the machine, should be the same or a derivative of the node
   266    provider ID. This is the equivalent of Google’s CloudComputeInstanceIdentifierOID, which we can
   267    reuse for a proof of concept (1.3.6.1.4.1.11129.2.1.21).
   268  
   269  #### CSR PEM Blocks
   270  
   271  The following blocks will be added to CSRs following Section 2 of [RFC7468].
   272  
   273  | Block Name                                 | Description                                          |
   274  | ------------------------------------------ | ---------------------------------------------------- |
   275  | KUBELET AUTHENTICATOR ATTESTATION PROVIDER | string describing the attestation provider           |
   276  | KUBELET AUTHENTICATOR ATTESTATION DATA     | the actual attestation data to perform validation on |
   277  
   278  #### Attestation data
   279  
   280  Attestation data will be appended with the following headers and footers and MUST
   281  be base64 encoded.
   282  
   283  Example CSR:
   284  ```
   285  -----BEGIN ATTESTATION DATA-----
   286  S25vd2luZyBtZSBBbGFuIFBhcnRyaWRnZSwga25vd2luZyB5b3UgS3ViZXJuZXRlcyBjbHVzdGVyLCBhaGEh
   287  -----END ATTESTATION DATA-----
   288  ```
   289  The format of the attestation block is left to the provider.
   290  
   291  #### Core Specification
   292  - Core Cluster API MUST provide the following implementations of CSRs and signers:
   293    - `cluster.x-k8s.io/kube-apiserver-client-kubelet-insecure` which implement an “Always Allow” type
   294      signer that provides equivalent security to Cluster API v1alpha3. This is only to be used for
   295      providers where no secure mechanism exists.
   296  
   297  - Core Cluster API MIGHT provide the following implementations of CSRs and signers:
   298    - `cluster.x-k8s.io/kube-apiserver-client-kubelet-tpm` and `cluster-x-k8s-io/kubelet-serving-tpm`
   299      - Will implement TPM-based certificate signers and requesters based on the
   300        [cloud-provider-gcp implementation].
   301      - We will additionally implement a challenge-response mechanism, similar to that done in
   302        [SPIRE's TPM plugin]. This proposal will be updated with the implementation.
   303      - However, since the mechanism for retrieving endorsement keys varies across
   304      platforms, the TPM signer will additionally require a provider specific mechanism to provide the
   305      TPM Endorsement Key's CA.
   306  
   307  #### Provider Specification
   308  
   309  ##### All providers
   310  - All providers MUST insert a ProviderID within the KubernetesNodeProviderIdentifierOID extension
   311    attribute of the CSR.
   312  - All signer names MUST be filled in by the provider’s controller in
   313    InfraCluster.Status.KubeletClientCertificateSigner and
   314    InfraCluster.Status.KubeletServingCertificateSigner if the attestation controller is running.
   315  - All providers SHOULD implement trust-on-first-use type mechanisms to prevent replay attacks. We
   316    defer to providers how endpoint or authentication data is recorded to validate endpoints.
   317  
   318  ##### Insecure providers
   319  - An insecure provider CANNOT implement certificate rotation or kubelet serving certificate signing.
   320  - InfraCluster.Status.KubeletClientCertificateSigner MUST be set to
   321    cluster.x-k8s.io/kube-apiserver-client-kubelet-insecure.
   322  - An insecure provider MUST use the cluster.x-k8s.io/kube-apiserver-client-kubelet-insecure signer.
   323  
   324  ##### Secure providers
   325  - A secure provider MUST implement certificate rotation and kubelet server certificate signing.
   326  - A provider must register signers of:
   327      - `cluster-x-k8s-io/kube-apiserver-client-kubelet-<provider>`
   328      - `cluster-x-k8s-io/kubelet-serving-<provider>`
   329  - A secure provider MUST implement a secure attestation mechanism, based upon PEM-encoded blocks
   330    within the Certificate Signing Request.
   331  - Where a secure provider’s attestation mechanism does not include a challenge-response, nonce or
   332    timestamp to protect against replay attacks, the mechanism MUST implement a secondary time-limited
   333    attestation (e.g. AWS Instance Identity document + AWS HMACv4 signature).
   334  - A provider’s signer MUST run on the management cluster.
   335  
   336  ##### TPM based providers
   337  - A TPM provider MUST use the following certificate signers
   338      - `cluster-x-k8s-io/kube-apiserver-client-kubelet-tpm`
   339      - `cluster-x-k8s-io/kubelet-serving-tpm`
   340  - A TPM provider MUST annotate new CSRs as follows:
   341      - Key: cluster-x-k8s-io/tpm-endorsement-key
   342    - Value: Platform-specific endorsement key (e.g., retrieved from GCP Shielded VM API or VMware
   343      vCenter).
   344  
   345  #### Kubeadm
   346  Since this proposal essentially takes over part of the node registration process from kubeadm, we
   347  will require the following changes:
   348  - kubeadm COULD allow opt-out of kubeadm setting up ClusterRoleBindings between the system:nodes
   349    group and the `system:certificates.k8s.io:certificatesigningrequests:selfnodeclient` permission,
   350    so that certificate renewals must go through re-attestation.
   351  - Kubeadm COULD allow opt-out of kubeadm setting up `kubeadm:node-autoapprove-bootstrap` cluster
   352    role binding. This is deferred to a future Kubeadm design and release, and for this proposal, we
   353    will add fields to KubeadmControlPlane to remove these node groups and bindings post control plane
   354    initialisation.
   355  
   356  The idea is to rely on the [client-go auth exec mechanism] of kubeconfigs with local cache
   357  directory, when kubelet wants to talk to the apiserver it will call on the kubelet authenticator to
   358  get a client certificate.
   359  
   360  #### Changes to the Cluster and core Cluster API controller
   361  
   362  ``` yaml
   363  spec:
   364    security:
   365      kubeletAuthentication: true
   366      authorizedAttestors:
   367      - contosoCloud
   368  ```
   369  
   370  #### Changes to KubeadmControlPlane resources and controller
   371  
   372  The cluster field if set will be read by KCP and remove the `kubeadm:node-autoapprove-bootstrap`
   373  cluster role binding.
   374  
   375  #### Changes to Cluster API Bootstrap Provider Kubeadm
   376  
   377  If the kubeletAuthentication field is set for the cluster, CABPK will
   378  default `--rotate-server-certificates` on NodeRegistrationOptions.ExtraArgs for the kubeadm
   379  configuration. If KubeletConfiguration is supported within Cluster API v1alpha4, we
   380  will opt to set ServerTLSBootstrap on KubeletConfiguration instead.
   381  
   382  CABPK will also update the runcmds for cloud-init / Ignition such that the authenticator is set up
   383  with the initial bootstrap token.
   384  
   385  ##### Changes to token rotation
   386  
   387  Token rotation in CABPK is currently as follows:
   388  
   389  * If the token is for a Machine, renews the token TTL until the Machine has reached the
   390    InfrastructureReady == True condition, at which point the TTL clock is run out.
   391    * CABPK does not wait for Node Ready at present because we cannot ensure the machine bootstrap has
   392      been deliberately interrupted such that it may be used to register an arbitrary node.
   393  * If the token is for a MachinePool, rotate the token when the TTL is hit.
   394    * Since tokens are used for multiple machines to self-approve CSRs, we minimise token reuse
   395      opportunities by rotating it.
   396    * This causes issues for infrastructure provider mechanisms for MachinePools (User Story 2).
   397  
   398  When cluster.Spec.Security.KubeletAuthentication is set to true, CABPK will switch to this alternate
   399  behaviour, as there is no auto-approval of node CSRs:
   400  * If the token is for a Machine, renew the token TTL until the Machine is Ready (i.e. kubelet has
   401    successfully registered and a ProviderID exists)
   402  * If the token is for a MachinePool, renew the token TTL for the lifetime of the MachinePool.
   403    * This should be safe, as in the event of a compromise, administrators should replace the entire
   404      MachinePool.
   405  
   406  
   407  #### Kubelet authenticator flow
   408  
   409  The authenticator will be responsible for updating the kubelet client certificates only.
   410  
   411  ##### Client CSR flow
   412  
   413  ![client auth](images/kubelet-authentication/client-authenticator-flow.png)
   414  
   415  ##### Serving CSR handling
   416  
   417  For the Kubelet serving certificate, we intend to enable serving certificate TLS bootstrapping on
   418  Kubelet via the ServerTLSBootstrap settings of Kubelet's configuration.
   419  
   420  This will cause Kubelet to not generate a self-signed certificate for serving and instead
   421  submit CSRs for the initial certificate and rotation to the API server.
   422  
   423  The attestation controller will validate the following:
   424  
   425  * CSR spec.username field is of the form system:node:<nodeName> and spec.groups contains
   426    system:nodes
   427  * Only contains digital signature, server auth and key encipherment usages.
   428  * Only has IP and DNS subjectAltNames that belong to the requesting node. We defer to
   429    the infrastructure provider if it makes calls to the cloud provider for verification.
   430  
   431  ### Risks and Mitigations
   432  
   433  There may be additional security risks being introduced in this design. In order to mitigate this,
   434  this proposal will be taken to SIG Security and SIG Auth for review **before the beta graduation**.
   435  
   436  ## Alternatives
   437  
   438  #### Implement within the cloud providers instead of Cluster API
   439  Given that there is an existent implementation in cloud-provider-gcp, this could be extended to all
   440  of the cloud providers. However, there are some advantages to making Cluster API responsible for
   441  kubelet registration in that no changes to the assumptions around connectivity between management
   442  and workload clusters are required, neither does the signer need to be included as a static pod
   443  during control plane instantiation.
   444  
   445  #### Implement as authentication webhook, as per aws-iam-authenticator (Amazon EKS)
   446  If attestation was implemented as an authentication webhook, it would be in the critical path for
   447  all token-based authentication against the API server. It would also additionally be needed to be
   448  set up at workload cluster instantiation via a static pod and API server start up.
   449  
   450  #### SPIRE/SPIFFE
   451  
   452  SPIFFE (Secure Production Identity Framework for Everyone), and it's open source implementation in
   453  SPIRE form a set of standard frameworks for workload identity which is independent of any
   454  particular cluster technology. We spent some time investigating if SPIRE could be used as a baseline
   455  for kubelet authentication within Cluster API. However, [SPIRE currently requires a
   456  RDBMS][spire-architecture] independent of the Kubernetes API Server / etcd datastore. In the default
   457  mode, it uses SQLite.
   458  
   459  For the Day 0 provisioning of management clusters from Kind and then effecting a move of data, or
   460  otherwise bootstrapping SPIRE into a workload cluster on first boot presents a significant challenge
   461  as well as introducing a number of large dependencies into Cluster API. For this reason, we have
   462  chosen the main proposal instead.
   463  
   464  In addition, it isn't immediately clear how SVIDs (SANs starting with SPIFFE://\<identity\>) map to
   465  node identities accepted by the Kubernetes API Server. Node identity is most frequently the hostname
   466  in the CN of the certificate, and although there have been [initial discussions][spiffe-discussions]
   467  about how to make the Kubernetes API Server accept SVIDs directly, we do not want to wait on the
   468  resolution of that before proceeding.
   469  
   470  Where SPIFFE is desired end-to-end, it should in theory be possible to develop a CAPI kubelet
   471  authenticator provider that uses the SVID certificate as the CSR attestation data that is then
   472  exchanged for the kubelet certificate.
   473  
   474  ## Upgrade Strategy
   475  
   476  upgrades should be transparent for users:
   477  
   478  - Upgrading cluster API components shouldn't have effects on existing clusters
   479  - Upgrading workload clusters should also work fine, as CABPK would supply a bootstrap script in
   480    v1alpha4 and the current one when it's running in v1alpha3
   481  
   482  ## Additional Details
   483  
   484  ### Test Plan [optional]
   485  
   486  - E2E tests to be added to AWS, vSphere and Azure providers as each provider implements the signer
   487  - E2E tests to be added for the insecure signers for use with CAPD.
   488  Upgrade tests from latest minor release to latest main branch of Kubernetes
   489  
   490  
   491  ### Graduation Criteria [optional]
   492  
   493  #### Graduation to beta
   494  - E2E tests testing upgrades to latest main branch of Kubernetes are required such that Cluster API
   495    can make appropriate changes to node registration if kubelet or kubeadm behaviour changes.
   496  
   497  - Security review by SIG Auth and SIG Security
   498  #### Graduation to GA
   499  - External security review of the combined Cluster API and kubeadm model.
   500  
   501  
   502  ### Version Skew Strategy
   503  
   504  Any changes to the attestation data should be handled in a backward compatible manner by the
   505  infrastructure provider when implementing the interface used by the node-attestation-controller, by
   506  making sure it's able to convert an older attestation format to a newer one.
   507  
   508  This will be done by the controller verifying the version of the CSR sent by the CLI. If the
   509  version is mismatched, the controller will add an annotation listing supported versions. If the
   510  CLI supports the older version, it files a new CSR with the older format.
   511  
   512  
   513  ## Implementation History
   514  
   515  - [ ] 2020/10/07: [Initial Google doc][google-doc]
   516  - [ ] 2021/02/22: Open proposal PR
   517  - [ ] 2021/04/16: Upload PlantUML diagrams
   518  - [ ] 2021/04/27: Commentary on SPIFFE/SPIRE
   519  - [ ] 2021/04/28: Updates on token renewal, version skew and components
   520  - [ ] 2021/04/29: Update TPM text, add links to K8s GCP Cloud Provider and SPIRE TPM plugins.
   521  
   522  <!-- Links -->
   523  [community meeting]: https://docs.google.com/document/d/1Ys-DOR5UsgbMEeciuG0HOgDQc8kZsaWIWJeKJ1-UfbY
   524  [nist-sp-800-190]: https://csrc.nist.gov/publications/detail/sp/800-190/final
   525  [google-doc]: https://docs.google.com/document/d/12xBDKPbmzWGcPK0qp23rfqzDlqGqnXV_t5fuXUol0QA/edit
   526  [RFC7468]: https://tools.ietf.org/html/rfc7468#page-3
   527  [iana-issue]: https://github.com/kubernetes/k8s.io/issues/1959
   528  [spire-architecture]: https://spiffe.io/docs/latest/spire-about/spire-concepts/
   529  [spiffe-discussions]: https://github.com/kubernetes/community/blob/master/sig-auth/archive/meeting-notes-2020.md#december-9-11a---noon-pacific-time
   530  [client-go auth exec mechanism]: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#configuration
   531  [cloud-provider-gcp implementation]: https://github.com/kubernetes/cloud-provider-gcp/blob/master/cmd/gke-exec-auth-plugin/tpm.go#L76
   532  [SPIRE's TPM plugin]: https://github.com/bloomberg/spire-tpm-plugin#how-it-works