Tower reached the dev cluster with a ServiceAccount token that never expired, copied into four places. I wanted it gone, not rotated. The spec ended up doing more than that: checking what the token could really do turned up a path to far more power than a "read-only" identity should have, and that had to close first.
The token could create PipelineRuns in any namespace, and nothing constrained their shape. Chained with a privileged ServiceAccount elsewhere, that was a path to cluster-admin. Worked out from RBAC and config, never exercised.
Re-run and Cancel went from the browser through Backstage's generic Kubernetes proxy, which every signed-in user could reach. That bypassed Tower's ownership check entirely.
An admission policy pins the exact PipelineRun shape Tower sends. Re-run and Cancel moved to owner-gated backend routes, and the proxy now refuses anything but reads.
Since Glidepath API P6 (Oct 30, 2026) tower-actor can't write a PipelineRun at all. Its binding to backstage-tekton-rerun is deleted, and the shape policy, renamed glidepath-api-pipelinerun-shape, refuses every PipelineRun write from it and holds glidepath-api, which now starts and cancels runs, to the same shape. tower-actor keeps view, the break-glass binder and the service proxy to glidepath-api. The reader lost its Rekor, Testkube and tekton-results-relay service-proxy grants; its Role backstage-ingestor-tekton-results-proxy keeps the old name but names only glidepath-api. The tokens themselves didn't change.
| Option | Verdict | Why |
|---|---|---|
| Native federation | Chosen | Nothing stored, nothing new in the request path, the trust file reloads by itself, and claims are checked with CEL. |
| Secrets-store dynamic secret | Fallback | Short leases, but the store keeps a standing credential, and every Tower read depends on it being up. |
| Pinniped Concierge | Fallback | Same trust model, plus a component with CA-key-level privilege. For clusters whose API server flags can't change. |
| A token "minter" | Rejected | Its bootstrap credential can mint the full-power token, so the risk stays the same. |
| Short-lived client certificates | Rejected | Submitting a request needs a credential first, and certificates can't be revoked. |
The trust model is portable; the mechanism isn't. Managed control planes don't expose API server flags, so Tower picks how it gets a credential cluster by cluster. On the big clouds it's an exchange: the same projected token, traded for a cloud identity with a trust policy on its subject and audience. The reader and writer split carries over as two roles or two federated credentials. What gets coarser is the claim checking, and revocation is slower behind an exchange, because tokens already issued live until they expire.
One regression on the way, about 21 minutes long: a Backstage proxy quirk sent dev-cluster reads to the prod cluster once the stored token was removed. The local harness never runs in a cluster, so it couldn't have caught it. A small guard fixed it, and a cleaner fix is noted for later.