auth: resolve cluster context once per mirror wait, not per re-mint · Entire

auth: resolve cluster context once per mirror wait, not per re-mint

f209837→main·

toothbrush·1mo ago·4 files·+136 added/-59 removed

RepoScopedToken re-ran cluster discovery and context selection on every call, so each 401-driven re-mint during a long clone wait depended on discovery staying reachable — a transient outage or cache problem mid-wait could abort a wait that had already authorized.

Split the two phases: RepoTokenSource resolves the cluster's core and login context once at construction and exposes Token/Invalidate over a repocreds cache, so re-mints only re-exchange (refreshing the login JWT if needed). waitForMirrorClone builds one source up front and invalidates before re-minting on 401; RepoScopedToken stays as the one-shot wrapper for single probes.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

Sessions

e8421451a9d2View transcript

Changes

4

23 unmodified lines

// actionable message instead of the raw OAuth error. var ErrRepoTargetUnknown = errors.New("cluster has no servable mirror at this audience")

// repoExchangeTimeout bounds the HTTP calls behind one mint: the // /.well-known cluster discovery (disk-cached after the first call) and the // /oauth/token exchange. const repoExchangeTimeout = 30 * time.Second

// resolveContextForCluster is the discovery seam, swapped in tests so they // ... (remaining function explanation omitted)

// Token returns a repo-scoped token for repoSlug (the surface-prefixed repo // path, e.g. /gh/octocat/hello, joined verbatim to the cluster URL to form // the audience) and action ("pull" or "push"). Tokens are cached per // (repoSlug, action) until near expiry.

// Invalidate drops the cached (repoSlug, action) token so the next Token // call re-exchanges — for when the data plane rejected it (401) ahead of // its recorded expiry.

// TestRepoTokenSource_ReMintSkipsDiscovery asserts cluster discovery runs // once, at construction — re-mints after Invalidate (the clone wait's // 401 path) only re-exchange, so a discovery hiccup mid-wait can't abort a // wait that already authorized.

// TestWaitForMirrorClone_TimeoutBoundsAuthorization pins that --wait-timeout // covers the initial token mint, not just the probe loop: minting spans // cluster discovery and a possible login refresh, so a hung auth path must // be cut off by the user's wait budget.