From d32e82db12e89647f0b1186a3abebc3b83c8c870 Mon Sep 17 00:00:00 2001 From: David Eads Date: Mon, 9 Dec 2019 10:19:17 -0500 Subject: [PATCH] add multiple signers to CSRs --- keps/sig-auth/20190607-certificates-api.md | 52 +++++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/keps/sig-auth/20190607-certificates-api.md b/keps/sig-auth/20190607-certificates-api.md index 195775851f59..985e4374ea81 100644 --- a/keps/sig-auth/20190607-certificates-api.md +++ b/keps/sig-auth/20190607-certificates-api.md @@ -10,7 +10,7 @@ approvers: - "@liggitt" - "@smarterclayton" creation-date: 2019-06-07 -last-updated: 2019-09-04 +last-updated: 2019-12-09 status: implementable --- @@ -26,6 +26,7 @@ status: implementable - [Proposal](#proposal) - [Design Details](#design-details) - [Sequence of an Issuance](#sequence-of-an-issuance) + - [Signers](#signers) - [CertificateSigningRequest API Definition](#certificatesigningrequest-api-definition) - [Manual CSR Approval With Kubectl](#manual-csr-approval-with-kubectl) - [Automatic CSR Approval Implementations](#automatic-csr-approval-implementations) @@ -90,26 +91,26 @@ signer can interact. A client requesting a certificate post a CertificateSigningRequest to the Certificates API. The client may only provide the encoded [Certificate -Request](https://tools.ietf.org/html/rfc2986) and usages of the certificate in -the spec (and the standard object metadata) on the initial creation of the +Request](https://tools.ietf.org/html/rfc2986), usages of the certificate in +the spec, the standard object metadata, and the requested signer on the initial creation of the CertificateSigningRequest. The kube-apiserver also asserts authentication attributes of the requestor in the CertificateSigningRequest spec before committing it to storage so that they can be used later during CSR approval. The information contained in the spec is immutable after the request is created. -The approver updates approval status of the CertificateSigningRequest via the +An approver updates approval status of the CertificateSigningRequest via the CertificateSigningRequestStatus. The approval condition can only be updated via the `/approval` subresource allowing approval permission to be authorized independently of other operations on the CertificateSigningRequest. -Contingent on approval, the signer posts a signed certificate to the status. The +Contingent on approval, a signer posts a signed certificate to the status. The certificate field of the status can only be updated via the `/status` subresource allowing signing permission to be authorized independently of other operations on the CertificateSigningRequest. The API is designed to support the standard asynchronous controller model of Kubernetes where the approver and signer act as independent controllers of the -Certificates API. Since issuance is asynchronous, the approver can perform +Certificates API. Since issuance is asynchronous, an approver can perform out-of-band verification of the CSR before making an authorization decision. The approver is designed to be explicitly independent of the signer. This @@ -132,6 +133,31 @@ A typical successful issuance proceeds as follows. the `.Status.Certificate` field. 1. The requestor observes the update, and stores the certificate locally. +### Signers +CSRs have a `signerName` field which is used to specify which signer the CSR creator wants to sign the certificate. +To support migration from v1beta1 to v1, this required field will be defaulted in v1beta1, but not in v1: + 1. If it's a kubelet client certificate, it is assigned " kubernetes.io/kubelet-client". + 2. Otherwise, it is assign "kubernetes.io/legacy-unknown". + +Kubernetes provides the following well-known signers: + 1. kubernetes.io/kube-apiserver-client - signs certificates that will be honored as client-certs by the kube-apiserver. + Never auto-approved by kube-controller-manager. + 2. kubernetes.io/kubelet-client - signs client certificates that will be honored as client-certs by the kube-apiserver. + May be auto-approved by kube-controller-manager. + 3. kubernetes.io/kubelet-serving - signs serving certificates that are honored as a valid kubelet serving certificate + by the kube-apiserver, but has no other guarantees. Never auto-approved by kube-controller-manager. + 4. kubernetes.io/legacy-unknown - has no guarantees for trust at all. Some distributions may honor these as client + certs, but that behavior is not standard kubernetes behavior. Never auto-approved by kube-controller-manager. + +Distribution of trust happens out of band for these signers. Any trust outside of those described above are strictly +coincidental. For instance, some distributions may honor kubernetes.io/legacy-unknown as client-certificates for the +kube-apiserver, but this is a coincidence, not a standard. +None of these usages are related to ServiceAccount token secrets `.data[ca.crt]` in any way. That ca-bundle is only +guaranteed to verify a connection the kube-apiserver using the default service. + +To support HA upgrades, the kube-controller-manager will duplicate defaulting code for an empty `signerName` for one +release. + ### CertificateSigningRequest API Definition ```go @@ -145,6 +171,20 @@ type CertificateSigningRequest struct { type CertificateSigningRequestSpec struct { + // requested signer for the request. It is a scoped name in the form: `scope-hostname.com/name`. + // If empty, it will be defaulted for v1beta1: + // 1. If it's a kubelet client certificate, it is assigned " kubernetes.io/kubelet-client". + // 2. Otherwise, it is assign "kubernetes.io/legacy-unknown". + // In v1 it will be required. Distribution of trust for signers happens out of band. + // that will be honored by the kube-controller-manager signer after approval. + // 1. kubernetes.io/kube-apiserver-client - signs certificates that will be honored as client-certs by the kube-apiserver. Never auto-approved by kube-controller-manager. + // 2. kubernetes.io/kubelet-client - signs client certificates that will be honored as client-certs by the kube-apiserver. May be auto-approved by kube-controller-manager. + // 3. kubernetes.io/kubelet-serving - signs serving certificates that are honored as a valid kubelet serving certificate by the kube-apiserver, but has no other guarantees. + // 4. kubernetes.io/legacy-unknown - has no guarantees for trust at all. Some distributions may honor these as client certs, but that behavior is not standard kubernetes behavior. + // None of these usages are related to ServiceAccount token secrets `.data[ca.crt]` in any way. + // +required + SignerName string + // Base64-encoded PKCS#10 CSR data Request []byte