Trust anchor rotation reference

BEL provides automated trust anchor rotation in the form of a Kubernetes operator that runs on the cluster and a companion linkerd-trust CLI extension. See the trust-rotation configuration guide for an end-to-end walkthrough, and the BEL CLI reference for the linkerd trust commands.

Operator behavior and progress are tracked by a single cluster-scoped TrustAnchorRotation custom resource (API group trust.linkerd.io, version v1alpha1, short name tar). The operator chart creates one named cluster by default. You configure the desired behavior through its spec, and the operator reports observed rotation progress through its status subresource.

cert-manager prerequisite

The trust-rotation operator does not mint certificates itself. It builds on top of cert-manager, which remains responsible for generating and renewing the trust anchor and identity issuer. The operator provides the orchestration layer above cert-manager: it maintains the Linkerd trust bundle, refreshes the Linkerd control plane when the bundle changes, gates phase transitions on observed convergence, and makes the workflow resumable across operator restarts.

A few practical consequences of this division of labor:

  • cert-manager is a hard prerequisite. Without a working cert-manager installation that issues the trust anchor and identity issuer certificates, the operator has nothing to orchestrate.

  • trust-manager is no longer required. The trust-rotation operator maintains the linkerd-identity-trust-roots ConfigMap directly from the cert-manager-managed trust anchor secrets. After the initial bundle has been bootstrapped, trust-manager is not on the path.

  • Renewing certificates remains a cert-manager concern. The operator reacts to externally-initiated certificate changes (such as a cmctl renew on the trust anchor) by driving the rest of the rotation; it does not trigger issuance directly.

Pairing with the data plane operator

During the PropagatingTrustRoots phase the data plane operator pushes the accelerated workload-certificate refresh interval into each meshed pod by injecting the config.linkerd.io/proxy-additional-env annotation. This shortened interval lets workloads renew their identity certificates passively during through the issuer switch (RenewingWorkloadCerts phase), removing the need for one of the data plane restarts in a full rotation: two restarts instead of three.

Without the data plane operator, the accelerated interval has no consumer. At the issuer-renewal step, meshed workloads then have to either be restarted explicitly, or be left to renew their identity certificates at the proxy’s normal 24-hour interval. Either path eventually moves the cluster onto the new issuer; the restart is just the fast option.

How it works

At a high level, a full rotation moves through three groups of steps. First, bundle expansion: the trust bundle grows to hold both the old and new trust anchors, and that expanded bundle is propagated across the control plane and meshed workloads so every proxy trusts both anchors at once. Second, the issuer switch: the identity issuer is renewed onto the new anchor and workloads renew their certificates onto that new path while the expanded bundle keeps mTLS working throughout. Third, bundle reduction: once every workload has converged on the new issuer, the bundle shrinks back to the single new anchor and the change is propagated again, returning the cluster to a clean steady state.

The operator is driven by a cluster-scoped TrustAnchorRotation custom resource. Its status subresource exposes a small state machine, surfaced through the status.phase field, that the operator advances based on what it sees in the cluster:

  • Synced: steady state. The trust anchor and identity issuer are aligned and every meshed workload chains to them.

  • RefreshingControlPlane: the desired trust bundle has changed and the Linkerd control plane has not yet caught up. This phase fires both when the bundle expands at the start of a rotation and when it is reduced at the end.

  • PropagatingTrustRoots: the control plane is on the expanded bundle and meshed workloads are being restarted to pick it up.

  • WaitingForIdentityRotation: the expanded bundle has converged everywhere it needs to converge, and the operator is waiting for the user (or cert-manager) to renew the identity issuer. This is the one intentional manual step that remains.

  • RenewingWorkloadCerts: the issuer has been renewed and the operator is waiting for workloads to renew their identity certificates onto the new issuer path. To keep this window short, the operator publishes an accelerated renewal interval (default 5 minutes) that the data plane honors when paired with the data plane operator (see below).

  • RemovingOldTrustRoots: the new issuer is in place, workloads have converged, and the bundle is being reduced back to a single root.

The operator never advances unless the preconditions of the next phase are observable. If a rollout stalls, the rotation simply parks in its current phase and reports a blocking message in TrustAnchorRotation.status.blockingMessage, so on-call engineers can see what the operator is waiting on without reconstructing the system state by hand.

TrustAnchorRotation spec

The spec holds the desired configuration for trust-anchor rotation behavior.

FieldDescription
workloadCertificateRefreshIntervalInterval to temporarily configure for workload certificate refreshes while the rotation is accelerating certificate renewal. Default 5m.

TrustAnchorRotation status

The status subresource is populated by the operator and reflects the observed state of the rotation. It is the surface mirrored by linkerd trust inspect and by the operator’s Prometheus metrics.

FieldDescription
phaseCurrent high-level phase of the rotation workflow (see Phases below). Default Synced.
blockingMessageHuman-readable message describing why the rotation is currently waiting for convergence, if any.
activeIssuerFingerprintFingerprint of the Linkerd identity issuer certificate currently observed as active.
previousAnchorFingerprintFingerprint of the operator-managed linkerd-previous-anchor copy used to preserve overlap during rotation.
lastPhaseTransitionTimeTime when the rotation last entered the current phase.
workloadCertificateRefreshIntervalEffective temporary workload certificate refresh interval currently being enforced, if any.
trustBundleConvergence status for trust-bundle propagation across the relevant pods. See Convergence groups.
workloadCertificatesConvergence status for workload certificate rotation across meshed workloads. See Convergence groups.
sourceFingerprintsFingerprints observed for the configured trust-anchor sources. See status.sourceFingerprints.
conditionsAdditional condition records describing notable rotation states. See status.conditions.

Phases

status.phase advances through a state machine that the operator gates on observed cluster state. The full set of values:

PhaseDescription
SyncedSteady state. The trust anchor and identity issuer are aligned and every meshed workload chains to them.
RefreshingControlPlaneThe desired trust bundle has changed and the Linkerd control plane has not yet caught up. Fires both when the bundle expands and when it is reduced.
PropagatingTrustRootsThe control plane is on the expanded bundle and meshed workloads are being restarted to pick it up.
WaitingForRemoteClustersWaiting for remote clusters to converge (multicluster rotations).
WaitingForIdentityRotationThe expanded bundle has converged and the operator is waiting for the identity issuer to be renewed.
RenewingWorkloadCertsThe issuer has been renewed and the operator is waiting for workloads to renew their identity certificates.
RemovingOldTrustRootsThe new issuer is in place, workloads have converged, and the bundle is being reduced back to a single root.

Convergence groups

Both status.trustBundle and status.workloadCertificates share the same shape, reporting progress for a group of pods.

FieldDescription
statusAggregate convergence state for the group, one of Converging, Converged.
convergedPodsNumber of target pods currently observed to have converged.
targetPodsTotal number of pods included in this convergence group.

status.sourceFingerprints

Each entry reports the observed fingerprint for one configured trust-anchor source.

FieldDescription
fingerprintFingerprint of the certificate currently loaded from the source.
kindBacking resource type providing the certificate material, one of secret, configMap, inline. Default secret.
nameName of the referenced Secret or ConfigMap, when applicable.
namespaceNamespace of the referenced Secret or ConfigMap, when applicable.

status.conditions

Each entry is a single condition describing a stable observed state transition.

FieldDescription
typeCondition type identifier.
statusWhether this condition is currently active, one of True, False.
reasonProgrammatic reason identifier for the current condition state.
messageHuman-readable details for the condition.
lastTransitionTimeTime when this condition last changed status, reason, or message.

Example

apiVersion: trust.linkerd.io/v1alpha1
kind: TrustAnchorRotation
metadata:
  name: cluster
spec:
  workloadCertificateRefreshInterval: 5m
status:
  phase: PropagatingTrustRoots
  lastPhaseTransitionTime: "2026-06-01T12:00:00Z"
  blockingMessage:
    "Waiting for 2 pod(s) to converge on the expanded trust bundle"
  activeIssuerFingerprint: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
  previousAnchorFingerprint: "0f1e2d3c4b5a69788796a5b4c3d2e1f00f1e2d3c4b5a69788796a5b4c3d2e1f0"
  workloadCertificateRefreshInterval: 5m
  trustBundle:
    status: Converging
    convergedPods: 10
    targetPods: 12
  workloadCertificates:
    status: Converged
    convergedPods: 12
    targetPods: 12
  sourceFingerprints:
    - kind: secret
      name: linkerd-trust-anchor
      namespace: cert-manager
      fingerprint: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
    - kind: secret
      name: linkerd-previous-anchor
      namespace: linkerd
      fingerprint: "0f1e2d3c4b5a69788796a5b4c3d2e1f00f1e2d3c4b5a69788796a5b4c3d2e1f0"
  conditions:
    - type: OutOfOrderIssuerRotation
      status: "False"
      reason: IssuerRotationInOrder
      message:
        "identity issuer rotation is not ahead of trust-bundle convergence"
      lastTransitionTime: "2026-06-01T12:00:00Z"

You can watch the operator-managed status in real time (this requires yq):

watch -d -n 1 'kubectl get trustanchorrotations.trust.linkerd.io cluster \
    -o yaml | yq .status'