docs: describe auth comments in present tense · Entire
docs: describe auth comments in present tense
eaf01d1→main·
toothbrush·1mo ago·7 files·+35 added/-39 removed
Sweep of every comment touched by the COR-393/COR-395 stack for transition framing: RecordLoginContext no longer claims a dual-write or a best-effort contract, the git-remote-entire package doc drops the read-time migration, newContextTokenManager and the coreapi bearer source stop referencing the deleted singleton/static paths, and the NormalizeOriginURL doc loses its dangling AuthBaseURL pointer. Each now states the current behaviour and why it holds.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Sessions
fe2b80edc270View transcript
?\ Auth Refactor: Eliminate Static FallbacksClaude Code·Fable 5.[1m]·1 step
Changes
7
cmd
entire/cli
api
Mbase_url.go+5/-3
auth
Mclient.go+3/-3
Mcontexts.go+12/-15
Mrefresh.go+6/-7
Mlogin.go+2/-2
git-remote-entire
Mmain.go+1/-2
internal/coreapi
Mclient.go+6/-7
22 unmodified lines
73 unmodified lines
104
105
106
107
107
108
109
110
111
112
22 unmodified lines
BaseURLEnvVar = "ENTIRE_API_BASE_URL"
// AuthBaseURLEnvVar is the retired auth-origin override. Nothing reads
// its value anymore — RejectRemovedAuthEnv fails every command when it
// is set, pointing at `entire login --server`.
// its value — RejectRemovedAuthEnv fails every command when it is set,
// pointing at `entire login --server`.
AuthBaseURLEnvVar = "ENTIRE_AUTH_BASE_URL"
schemeHTTP = "http"
73 unmodified lines
// Mirrors auth-go's internal/oauthhttp.NormalizeOriginURL so the value the
// CLI hands to the manager as Issuer survives the manager's own normalisation
// pass byte-for-byte — see AuthBaseURL.
// pass byte-for-byte; a cosmetically-different origin (uppercase host,
// explicit :443, trailing slash) would otherwise be keyed under a different
// keyring slot than the manager later reads.
func NormalizeOriginURL(raw string) string {
trimmed := strings.TrimSpace(raw)
u, err := url.Parse(trimmed)
Mcmd/entire/cli/api/base_url.go+5/-3
230 unmodified lines
// secondsUntil computes seconds-until-expiry for a TokenSet with an
// absolute ExpiresAt. Returns 0 when no expiry is set or when ExpiresAt
// is already in the past (clock skew, scheduling delays) — historically
// ExpiresIn was non-negative and downstream loggers / display code don't
// expect to see a negative value.
// is already in the past (clock skew, scheduling delays) — ExpiresIn is
// contractually non-negative; downstream loggers and display code don't
// expect a negative value.
func secondsUntil(t *tokens.TokenSet) int {
if t.ExpiresAt.IsZero() {
return 0
Mcmd/entire/cli/auth/client.go+3/-3
13 unmodified lines
// defaultContextTokenTTL is the encoded keychain expiry used when a login
// token carries no usable exp claim (e.g. an opaque, non-JWT bearer). The
// server is the real authority on validity; this only governs when local
// readers consider the token stale, and we hold no refresh token to act on
// it, so a conservative non-zero value is enough to keep the entry usable.
// JWT carries no usable exp claim. The server is the real authority on
// validity; this only governs when local readers consider the token stale,
// so a conservative non-zero value is enough to keep the entry usable.
const defaultContextTokenTTL = time.Hour
// RecordLoginContext records a freshly obtained login token in the
// the same core gets its own context (named handle@host) instead of
// clobbering the first.
//
// activate controls current_context: login passes true (the just-completed
// login becomes active, kubectl use-context style); read-time migration
// passes false so it never silently switches the user's active account —
// it still sets current_context when none exists yet.
// activate controls current_context: true makes the just-completed login
// active (kubectl use-context style); false records it without switching
// the user's active account, though it still sets current_context when
// none exists yet.
//
// This is the contexts.json half of login's dual-write: the legacy
// entire-cli/<authBaseURL> keyring entry is still written by the caller so
// the control-plane readers keep working untouched during the transition.
// A login recorded here is visible to entiredb's CLIs (and the in-CLI git
// remote helper) because they share this file and keychain layout.
// This is the CLI's only credential write: a login recorded here is what
// every consumer resolves against — the control plane, the data API, the
// in-CLI git remote helper, and entiredb's CLIs, which share this file and
// keychain layout.
// Returns the context name on success. Errors are returned (not swallowed)
// so the caller can warn; login still succeeds on the legacy entry.
// Returns the context name on success.
func RecordLoginContext(rawToken, refreshToken string, activate bool) (string, error) {
claims, err := tokens.ParseClaims(rawToken)
if err != nil {
Mcmd/entire/cli/auth/contexts.go+12/-15
106 unmodified lines
// newContextTokenManager builds the per-context auth-go tokenmanager that both
// NewRefreshingLoginProvider and NewRefreshingResourceProvider sit on. Keying
// Issuer on c.CoreURL is the whole point: store reads, the refresh grant, and
// the STS exchange all target that context's core (the bug the singleton
// manager — pinned to AuthBaseURL — has when the active context lives on a
// different core).
// the STS exchange all target that context's core, so a multi-core user's
// credentials never travel to (or get keyed under) a host the context
// doesn't belong to.
//
// transport carries the caller's TLS configuration; allowInsecureHTTP permits
// an http:// core/resource for loopback/dev.
69 unmodified lines
// fetch) could replay the same single-use token and trip the server's
// reuse detection, revoking the whole family.
//
// Behaviour is a strict superset of the old read-only provider: a still
// valid token is returned with no network call; a context with no refresh
// token (e.g. a login predating offline_access) behaves exactly as before
// — valid token used, expired token surfaces a re-login error.
// A still-valid token is returned with no network call. A context with no
// stored refresh token degrades gracefully: valid token used, expired token
// surfaces a re-login error.
//
// transport carries the caller's TLS configuration; allowInsecureHTTP
// permits an http:// core for loopback/dev.
Mcmd/entire/cli/auth/refresh.go+6/-7
342 unmodified lines
// still cannot complete a login: RecordLoginContext is the sole
// persistence path and requires iss/handle claims to key the context,
// so a claims-free token fails there with a parse error. Entire-core
// always issues claim-bearing JWTs; legacy opaque-token servers are no
// longer supported.
// always issues claim-bearing JWTs; opaque-token-only servers are not
// supported.
func validateReceivedToken(rawToken, issuerURL string, now time.Time) error {
claims, err := tokens.ParseClaims(rawToken)
if errors.Is(err, tokens.ErrUnsignedJWT) {
Mcmd/entire/cli/login.go+2/-2
14 unmodified lines
// shared contexts.json: the cluster's cores come from the cluster_cores.json
// cache (or a live /.well-known fetch on miss), then the account is selected
// from local contexts. It then mints repo-scoped tokens by exchanging that
// context's login JWT. A pre-contexts.json login is migrated at read-time so
// existing users don't have to re-authenticate.
// context's login JWT.
package main
import (
Mcmd/git-remote-entire/main.go+1/-2
81 unmodified lines
func (p *providerSource) BearerAuth(ctx context.Context, _ OperationName) (BearerAuth, error) {
token, err := p.provide(ctx)
if err != nil {
// The static fallback path returns a bare ErrNotLoggedIn sentinel with
// no helpful text, so add the standard login hint. The active-context
// path (NewRefreshingLoginProvider) instead returns a tailored message
// that already names the context, its login server, and the exact
// re-login command — surface that verbatim rather than burying it under
// a generic prefix. Other failures (STS rejection, network) are
// likewise self-descriptive.
// The per-context provider returns a tailored message that already
// names the context, its login server, and the exact re-login command
// — surface it verbatim rather than burying it under a generic prefix;
// other failures (STS rejection, network) are likewise
// self-descriptive. A bare ErrNotLoggedIn (no tailored text) gets the
// standard login hint as a backstop.
if errors.Is(err, auth.ErrNotLoggedIn) {
return BearerAuth{}, fmt.Errorf("not logged in — run 'entire login': %w", err)
}