linkerdpki

package
v0.0.0-...-12e8104 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: AGPL-3.0 Imports: 29 Imported by: 0

Documentation

Overview

Package linkerdpki provides the Linkerd identity issuer rotation and monitoring logic used by the app-gateway PKI guardian. The algorithm is migrated verbatim from cli/pkg/terminus without semantic change.

Index

Constants

View Source
const (
	// DefaultLinkerdNamespace is the namespace hosting the Linkerd control
	// plane and the PKI Secrets the guardian maintains (platform os-* NS).
	DefaultLinkerdNamespace = "os-mesh"

	// PKISecretName is the single source of truth Secret storing ca.* and
	// issuer.* material for issuer rotation; access is restricted via RBAC.
	PKISecretName = "olares-linkerd-pki"

	// IssuerRotateThreshold triggers rotation when the issuer's remaining
	// validity drops below 6 months.
	IssuerRotateThreshold = 180 * 24 * time.Hour

	// IssuerLifetimeDays is the validity (3 years) of a freshly signed issuer.
	IssuerLifetimeDays = 1095

	// CALifetimeDays is the validity (30 years) of the cluster trust anchor CA.
	CALifetimeDays = 10950
)
View Source
const (
	// WebhookCertValidityDays is 100 years, aligned with EG control-plane certgen.
	WebhookCertValidityDays = 36500
)

Variables

This section is empty.

Functions

func BootstrapIfMissing

func BootstrapIfMissing(ctx context.Context, c client.Client, linkerdNS string) (created bool, err error)

BootstrapIfMissing ensures olares-linkerd-pki exists with valid CA+issuer material. If the Secret already exists with required keys, returns (false, nil) without mutation.

func EnsureWebhookCerts

func EnsureWebhookCerts(ctx context.Context, c client.Client, ns string, overwrite bool) error

EnsureWebhookCerts creates per-cluster Linkerd admission webhook TLS Secrets (100y, SAN=*.<ns>.svc) and syncs caBundle on the matching webhook configs. When overwrite is false and a Secret already has a matching SAN, the Secret is left unchanged (search3 lookup semantics) but caBundle is still reconciled.

func IssuerNeedsRotation

func IssuerNeedsRotation(issuerPEM []byte, now time.Time) (need bool, remaining time.Duration, err error)

IssuerNeedsRotation reports whether the issuer PEM should be rotated at now, returning the remaining validity. Exported for unit tests (TC-PKI-G01).

func MaintainLinkerdPKI

func MaintainLinkerdPKI(ctx context.Context, c client.Client, linkerdNS string) error

MaintainLinkerdPKI checks whether the vault issuer needs rotation, then always syncs linkerd-identity-issuer and restarts linkerd-identity when it still lags the vault.

func SyncIdentityToLinkerd

func SyncIdentityToLinkerd(ctx context.Context, c client.Client, linkerdNS string) (changed bool, err error)

SyncIdentityToLinkerd copies issuer/trust from olares-linkerd-pki into Linkerd identity mount points. Idempotent: no-op when remote PEM already matches material.

Types

type Controller

type Controller struct {
	// contains filtered or unexported fields
}

Controller runs a level-triggered reconcile loop: an immediate pass at start, then one pass per interval, with exponential backoff on transient failures. It never calls os.Exit; the process exits only when ctx is cancelled.

func NewController

func NewController(c client.Client, ns string, interval time.Duration, probes *ProbeState, metrics *Metrics) *Controller

NewController wires the reconcile loop to its client, probes and metrics.

func (*Controller) Run

func (c *Controller) Run(ctx context.Context)

Run drives reconciliation until ctx is cancelled, returning on graceful shutdown. Transient failures are retried with backoff and never terminate.

type Material

type Material struct {
	CACrt     []byte
	CAKey     []byte
	IssuerCrt []byte
	IssuerKey []byte
}

Material holds trust anchor and issuer PEM bytes for the Linkerd PKI Secret.

type Metrics

type Metrics struct {
	// contains filtered or unexported fields
}

Metrics holds the guardian's Prometheus collectors on a private registry so the controller can be instantiated more than once (e.g. in tests) without a duplicate-registration panic. Metrics never carry PEM/private-key material.

func NewMetrics

func NewMetrics() *Metrics

NewMetrics builds and registers the guardian metrics (detailed design §6.1).

func (*Metrics) Handler

func (m *Metrics) Handler() http.Handler

Handler returns the /metrics HTTP handler bound to the private registry.

func (*Metrics) IncFailure

func (m *Metrics) IncFailure(reason string)

IncFailure increments the failure counter for the given reason.

func (*Metrics) MarkSuccess

func (m *Metrics) MarkSuccess(t time.Time)

MarkSuccess records the timestamp of a successful reconcile.

func (*Metrics) ObserveReconcile

func (m *Metrics) ObserveReconcile(d time.Duration)

ObserveReconcile records the duration of one ReconcileOnce.

func (*Metrics) SetIssuerNotAfterSeconds

func (m *Metrics) SetIssuerNotAfterSeconds(v float64)

SetIssuerNotAfterSeconds records the issuer remaining validity in seconds.

type ProbeState

type ProbeState struct {
	// contains filtered or unexported fields
}

ProbeState tracks controller liveness/readiness for the HTTP probes exposed on GUARDIAN_HTTP_ADDR. It is safe for concurrent use.

func NewProbeState

func NewProbeState(interval time.Duration) *ProbeState

NewProbeState returns a ProbeState sized to the reconcile interval.

func (*ProbeState) HealthHandler

func (p *ProbeState) HealthHandler(w http.ResponseWriter, _ *http.Request)

HealthHandler serves /healthz: 200 while the heartbeat is younger than livenessHeartbeatThreshold.

func (*ProbeState) Heartbeat

func (p *ProbeState) Heartbeat()

Heartbeat refreshes the liveness timestamp; called on every loop wake-up.

func (*ProbeState) MarkAttempted

func (p *ProbeState) MarkAttempted()

MarkAttempted records that at least one reconcile attempt has completed (success or predictable transient), satisfying /startupz.

func (*ProbeState) MarkClientReady

func (p *ProbeState) MarkClientReady()

MarkClientReady records that the in-cluster client has been constructed and seeds the heartbeat so /healthz is fresh before the first reconcile.

func (*ProbeState) MarkSuccess

func (p *ProbeState) MarkSuccess()

MarkSuccess records a successful reconcile for /readyz and refreshes liveness.

func (*ProbeState) ReadyHandler

func (p *ProbeState) ReadyHandler(w http.ResponseWriter, _ *http.Request)

ReadyHandler serves /readyz: 200 when the last successful reconcile is within readinessIntervalMultiplier x interval.

func (*ProbeState) StartupHandler

func (p *ProbeState) StartupHandler(w http.ResponseWriter, _ *http.Request)

StartupHandler serves /startupz: 200 once the client is ready and one reconcile attempt has been made.

Jump to

Keyboard shortcuts

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