Skip to content
This repository was archived by the owner on May 27, 2022. It is now read-only.
This repository was archived by the owner on May 27, 2022. It is now read-only.

Consider honoring Kubernetes CSR spec.expirationSeconds to control cert duration #37

@enj

Description

@enj

The GA requirements for the Kubernetes CSR Duration KEP state:

Inform external signer implementations of the spec.expirationSeconds field

smart-edge-open/edgeservices is an external signer implementation. This diff outlines how this signer may be updated to honor this new field:

diff --git a/pkg/certsigner/certsigner.go b/pkg/certsigner/certsigner.go
index 927299b..96bedf1 100644
--- a/pkg/certsigner/certsigner.go
+++ b/pkg/certsigner/certsigner.go
@@ -22,6 +22,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/informers"
 	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/util/certificate/csr"
 	capihelper "k8s.io/kubernetes/pkg/apis/certificates/v1"
 	"k8s.io/kubernetes/pkg/controller/certificates"
 	"k8s.io/kubernetes/pkg/controller/certificates/authority"
@@ -99,7 +100,7 @@ func (c *CertificateSigner) handleCSR(csr *capi.CertificateSigningRequest) error
 	}
 
 	certData, err := c.ca.Sign(x509cr.Raw, authority.PermissiveSigningPolicy{
-		TTL:    c.cfg.CertTTL.Duration,
+		TTL:    c.duration(csr.Spec.ExpirationSeconds),
 		Usages: csr.Spec.Usages,
 	})
 	if err != nil {
@@ -118,6 +119,28 @@ func (c *CertificateSigner) handleCSR(csr *capi.CertificateSigningRequest) error
 	return nil
 }
 
+func (c *CertificateSigner) duration(expirationSeconds *int32) time.Duration {
+	defaultDuration := c.cfg.CertTTL.Duration
+
+	if expirationSeconds == nil {
+		return defaultDuration
+	}
+
+	// honor requested duration is if it is less than the default TTL
+	// use 10 min (2x hard coded backdate above) as a sanity check lower bound
+	const min = 10 * time.Minute
+	switch requestedDuration := csr.ExpirationSecondsToDuration(*expirationSeconds); {
+	case requestedDuration > defaultDuration:
+		return defaultDuration
+
+	case requestedDuration < min:
+		return min
+
+	default:
+		return requestedDuration
+	}
+}
+
 func loadCA(certPath, keyPath string) (authority.CertificateAuthority, error) {
 	caCert, err := tls.LoadX509KeyPair(certPath, keyPath)
 	if err != nil {

Note that this requires Kubernetes v1.22+

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions