cert

package
v0.10.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 12, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package cert provides a generic, consumer-agnostic TLS certificate lifecycle manager for Kubernetes operators.

It supports two primary modes of operation:

  1. Self-Signed (Auto-Bootstrap & Rotation): This package implements a production-grade Split-Secret PKI architecture.

    Architecture: - Root CA: Generated once and stored in a Kubernetes Secret (name configured via Options). This secret should NOT be mounted to any pod to prevent key compromise. - Server Cert: Signed by the Root CA and stored in a separate Secret.

    Lifecycle: - Bootstrap: On startup, checks if the secrets exist. If not, generates them. - Rotation: A background loop checks for expiration hourly. If the server cert is expiring (or the CA changes), it automatically renews the secrets. - Hooks: After reconciling PKI, an optional PostReconcileHook is called with the CA bundle. Consumers use this for tasks like patching webhook configurations. - Projection Wait: Optionally waits for the Kubelet to project secret files to disk before returning from Bootstrap (useful for projected volume mounts). - Observability: Emits standard Kubernetes Events for all rotation actions.

  2. External (e.g., cert-manager): In this mode, certificates are provisioned by an external controller and the consumer simply points to the correct directory. The cert package is not used.

Usage:

mgr := cert.NewManager(client, recorder, cert.Options{
    Namespace:        "my-ns",
    CASecretName:     "my-ca-secret",
    ServerSecretName: "my-server-certs",
    ServiceName:      "my-service",
})
if err := mgr.Bootstrap(ctx); err != nil {
    // handle error
}

Index

Constants

View Source
const (
	// Organization is the default organization name used in generated certificates.
	Organization = "Multigres Operator"
	// CAValidityDuration is the duration the CA certificate is valid for (10 years).
	CAValidityDuration = 10 * 365 * 24 * time.Hour
	// ServerValidityDuration is the duration the server certificate is valid for (1 year).
	ServerValidityDuration = 365 * 24 * time.Hour
)
View Source
const (
	CertFileName = "tls.crt"
	KeyFileName  = "tls.key"

	// RotationThreshold is the buffer before expiry at which certs are rotated (30 days).
	RotationThreshold = 30 * 24 * time.Hour
)

Variables

This section is empty.

Functions

This section is empty.

Types

type CAArtifacts

type CAArtifacts struct {
	Cert    *x509.Certificate
	Key     *ecdsa.PrivateKey
	CertPEM []byte
	KeyPEM  []byte
}

CAArtifacts holds the Certificate Authority keys and PEM-encoded data.

func GenerateCA

func GenerateCA(organization string) (*CAArtifacts, error)

GenerateCA creates a new self-signed Root CA using ECDSA P-256. If organization is empty, the package-level Organization constant is used.

func ParseCA

func ParseCA(certPEM, keyPEM []byte) (*CAArtifacts, error)

ParseCA decodes PEM data back into crypto objects for signing usage.

type CertRotator

type CertRotator struct {
	Client   client.Client
	Recorder record.EventRecorder
	Options  Options
}

CertRotator manages certificate lifecycle: creation, rotation, and optional post-reconcile hooks. It is not webhook-specific — consumers configure behavior via Options.

func NewManager

func NewManager(c client.Client, recorder record.EventRecorder, opts Options) *CertRotator

NewManager creates a new CertRotator with the provided client, recorder, and options.

func (*CertRotator) Bootstrap

func (m *CertRotator) Bootstrap(ctx context.Context) error

Bootstrap runs at startup to ensure PKI is healthy. When WaitForProjection is true, it blocks until the cert file on disk matches the Secret content.

func (*CertRotator) Start

func (m *CertRotator) Start(ctx context.Context) error

Start runs the background rotation loop. It blocks until ctx is cancelled. Implements the controller-runtime Runnable interface.

type Options

type Options struct {
	// Required fields.
	Namespace        string
	CASecretName     string
	ServerSecretName string
	ServiceName      string

	// Owner is an optional Kubernetes object to set as the controller owner reference
	// on the generated secrets. When set, secrets are garbage-collected if the owner
	// is deleted. When nil, secrets are created without an owner reference.
	Owner client.Object

	// CertDir is the directory where the server cert is expected on disk.
	// Only used when WaitForProjection is true.
	CertDir string

	// RotationInterval is how often the background rotation loop runs.
	// Defaults to 1 hour.
	RotationInterval time.Duration

	// ComponentName is used in event messages (e.g., "Generated new <ComponentName> server certificate").
	// Defaults to "cert".
	ComponentName string

	// Organization overrides the certificate Organization field.
	// Defaults to the package-level Organization constant ("Multigres Operator").
	Organization string

	// AdditionalDNSNames are extra DNS SANs appended to the auto-generated
	// service DNS names (<svc>.<ns>.svc, <svc>.<ns>.svc.cluster.local).
	AdditionalDNSNames []string

	// ExtKeyUsages overrides the extended key usages for generated server certificates.
	// Defaults to [x509.ExtKeyUsageServerAuth].
	ExtKeyUsages []x509.ExtKeyUsage

	// WaitForProjection controls whether Bootstrap blocks until the cert file
	// appears on disk matching the Secret content. Set to true when using
	// Kubelet projected volumes (e.g., webhook servers).
	WaitForProjection bool

	// PostReconcileHook is called after the CA and server cert have been ensured.
	// Receives the CA bundle PEM bytes. Use this for consumer-specific tasks
	// like patching webhook configurations with the CA bundle.
	// If nil, no hook is called.
	PostReconcileHook func(ctx context.Context, caBundle []byte) error

	// Labels are applied to generated Secret objects. This is required when
	// secrets are created outside the operator namespace, because the informer
	// cache filters secrets by label (e.g., managed-by) in non-operator namespaces.
	// Without the correct labels, secrets are invisible to the cached client,
	// causing Get to return NotFound even after Create succeeds.
	Labels map[string]string
}

Options configures the CertRotator behavior. Consumers provide their own secret names, hooks, and owner references to make this package fully generic.

type ServerArtifacts

type ServerArtifacts struct {
	CertPEM []byte
	KeyPEM  []byte
}

ServerArtifacts holds the server certificate PEM-encoded data.

func GenerateServerCert

func GenerateServerCert(
	ca *CAArtifacts,
	commonName string,
	dnsNames []string,
	opts ...ServerCertOption,
) (*ServerArtifacts, error)

GenerateServerCert creates a leaf certificate signed by the provided CA. By default, the certificate includes only x509.ExtKeyUsageServerAuth. Use WithExtKeyUsages to override this (e.g., for mutual TLS).

type ServerCertOption

type ServerCertOption func(*serverCertConfig)

ServerCertOption configures optional behavior for GenerateServerCert.

func WithExtKeyUsages

func WithExtKeyUsages(usages ...x509.ExtKeyUsage) ServerCertOption

WithExtKeyUsages overrides the default extended key usage for the generated server certificate. The default is x509.ExtKeyUsageServerAuth. Use this when mutual TLS is needed (e.g., pgBackRest requires both ServerAuth and ClientAuth).

func WithOrganization

func WithOrganization(org string) ServerCertOption

WithOrganization overrides the default certificate Organization field.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL