Skip to content

Commit

Permalink
add multiple signers to CSRs
Browse files Browse the repository at this point in the history
  • Loading branch information
deads2k committed Dec 9, 2019
1 parent 9f951d2 commit d32e82d
Showing 1 changed file with 46 additions and 6 deletions.
52 changes: 46 additions & 6 deletions keps/sig-auth/20190607-certificates-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ approvers:
- "@liggitt"
- "@smarterclayton"
creation-date: 2019-06-07
last-updated: 2019-09-04
last-updated: 2019-12-09
status: implementable
---

Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

Expand Down

0 comments on commit d32e82d

Please sign in to comment.