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

`f209837`→[main](/content/gh/entireio/cli/commits/main/index.html)·

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

- cmd/entire/cli
  - auth
    - Mrepo_token.go+54/-30
    - Mrepo_token_test.go+44/-6
  - Mrepo_mirror_probe.go+29/-14
  - Mrepo_mirror_test.go+9/-9

```plaintext
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.
