Documentation
¶
Overview ¶
Package repocreds exchanges a logged-in user's login JWT for short-lived repo-scoped JWTs (TokenScopedJWT) and caches them per (audience, action).
Used by client/client.go to authenticate per-repo /api/v1/repos/... calls against entire-server, and by cmd/git-remote-entire to authenticate git smart-HTTP push/pull. Both surfaces share the same RFC 8693 token-exchange endpoint (POST /oauth/token on entire-core) but pass different audience shapes — by-ULID (/git/repo/<ULID>) for client.go, by-slug (/et/<owner>/<repo>) for git-remote-entire — so the Cache is neutral on the audience format: callers compute audienceSuffix themselves and the cache keys on it.
Index ¶
Constants ¶
const SafetyMargin = time.Minute
SafetyMargin is subtracted from the server's expires_in so callers rotate before actual expiry. One minute covers clock skew and gives slow downstream RPCs a fresh token. Matches admincreds.safetyMargin so the two cred caches don't diverge on freshness semantics.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache holds repo-scoped JWTs minted by exchanging a login JWT at entire-core's /oauth/token endpoint. Keyed by (audienceSuffix, action) so a single Cache can hold tokens for many repos and both pull/push at once.
The map mutex (mu) is held only long enough to find-or-create a per-key entry; the network exchange runs under the entry's own mutex. This lets exchanges for different keys proceed concurrently while still de-duplicating concurrent fetches for the same key.
func New ¶
func New(coreURL, clusterURL string, loginJWTProvider LoginJWTProvider, httpClient *http.Client) *Cache
New constructs a Cache. coreURL is the issuer URL of the login JWT; clusterURL is the entiredb cluster the resulting JWT will target (audience = clusterURL + audienceSuffix). Trailing slashes are trimmed.
func (*Cache) Invalidate ¶
Invalidate drops any cached token for (audienceSuffix, action). Callers invoke this on 401 from the data plane so the next Token call re-mints instead of replaying the rejected one.
func (*Cache) Token ¶
Token returns a valid repo-scoped JWT for the (audienceSuffix, action) pair, exchanging against /oauth/token if no cached entry exists or the cached one has crossed the safety margin. Concurrent callers serialize on the mutex; a single fetch satisfies all waiters.
audienceSuffix is the path portion of the audience claim — e.g. "/git/repo/<ULID>" or "/et/<owner>/<repo>". action is "pull" or "push".
type LoginJWTProvider ¶
LoginJWTProvider returns the current login JWT. Callers wire this to their own refresh logic (e.g. proactive refresh, 401 retry) so the Cache always exchanges with the live parent token, never a captured-then-stale copy.