Skip to content

Extract shared OAuthTokenSource into pkg/auth/tokensource#5090

Merged
yrobla merged 3 commits intomainfrom
issue-5050
Apr 29, 2026
Merged

Extract shared OAuthTokenSource into pkg/auth/tokensource#5090
yrobla merged 3 commits intomainfrom
issue-5050

Conversation

@yrobla
Copy link
Copy Markdown
Contributor

@yrobla yrobla commented Apr 28, 2026

Summary

Both pkg/llm and pkg/registry/auth implemented the same four-tier OAuth token strategy (in-memory cache → secrets-cached access token → refresh token → browser OIDC/PKCE). This extracts that logic into a single shared package, pkg/auth/tokensource, and rewires both consumers as thin wrappers.

Behavior changes (intentional):

  1. Registry path now has cross-process access-token caching. The shared OAuthTokenSource writes a <key>_AT secret after each successful token fetch (expiry encoded in the value). Concurrent short-lived thv processes can reuse this cached AT instead of all racing to exchange the same refresh token — preventing invalid_grant errors from OIDC providers that rotate refresh tokens on each exchange. This is new for the registry path (the old oauth_token_source.go did not have this tier).

  2. Registry path now wraps its restored token source with PersistingTokenSource. Rotated refresh tokens are re-persisted after a cache restore, matching the LLM path and fixing a gap where a provider-rotated refresh token would be lost on the next invocation.

Fixes #5050
Incorporates #5066

Type of change

  • Bug fix
  • New feature
  • Refactoring (no behavior change)
  • Other (describe): Refactoring with intentional behavior improvements — see above

Test plan

  • Unit tests (task test)
  • E2E tests (task test-e2e)
  • Linting (task lint-fix)
  • Manual testing (describe below)

API Compatibility

  • This PR does not break the v1beta1 API, OR the api-break-allowed label is applied and the migration guidance is described above.

Changes

File Change
pkg/auth/tokensource/tokensource.go New shared package: four-tier OAuthTokenSource, DeriveSecretKey, EnsureOfflineAccess
pkg/auth/tokensource/preemptive.go Preemptive refresh chain (withPreemptiveRefresh, withPreemptiveRefreshFrom)
pkg/auth/oauth/noncaching.go NonCachingRefresher — always performs a network round-trip, prevents preemptive-window thrashing
pkg/llm/tokensource.go Reduced to type aliases + thin constructor over shared package
pkg/registry/auth/auth.go Reduced to thin constructor over shared package; updateRegistryTokenRef simplified
pkg/registry/auth/oauth_token_source.go Deleted — superseded by shared package

Does this introduce a user-facing change?

The registry path gains cross-process AT caching (extra keyring/secrets writes). Users with very restrictive keyring write policies may need to allow writes to <key>_AT keys. In practice this is transparent and improves reliability for concurrent thv invocations.

Special notes for reviewers

  • The _AT cache key is KeyProvider() + "_AT". For registry, KeyProvider returns either CachedRefreshTokenRef or REGISTRY_OAUTH_<8hex>, so the AT key is e.g. REGISTRY_OAUTH_ab12cd34_AT.
  • cacheAccessToken suppresses write errors (debug log only) — a keyring write failure degrades gracefully to a full refresh on the next call.
  • makeTokenPersister writes "" to key+"_AT" to invalidate the AT cache after a refresh token rotation (rather than DeleteSecret, for provider compatibility).

Large PR Justification

This is a refactor to unify OAuthTokenSource used in several places. It reduces code duplication and provides better integration with cross-process token caching as a side effect.

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large PR Detected

This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.

How to unblock this PR:

Add a section to your PR description with the following format:

## Large PR Justification

[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformation

Alternative:

Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.

See our Contributing Guidelines for more details.


This review will be automatically dismissed once you add the justification section.

@github-actions github-actions Bot added the size/XL Extra large PR: 1000+ lines changed label Apr 28, 2026
@yrobla yrobla requested a review from Copilot April 28, 2026 13:21
@github-actions github-actions Bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 28, 2026
@github-actions github-actions Bot dismissed their stale review April 28, 2026 13:23

Large PR justification has been provided. Thank you!

@github-actions
Copy link
Copy Markdown
Contributor

✅ Large PR justification has been provided. The size review has been dismissed and this PR can now proceed with normal review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors duplicated OAuth/OIDC token acquisition logic (in-memory cache → secrets-cached access token → refresh token restore → interactive browser PKCE) out of pkg/llm and pkg/registry/auth into a shared pkg/auth/tokensource package, and rewires both consumers to use it. This also brings the registry path in line with the LLM path by persisting rotated refresh tokens after cache restore.

Changes:

  • Added pkg/auth/tokensource shared OAuthTokenSource implementation (plus unit/regression tests).
  • Updated LLM and registry token source wrappers to delegate to the shared package.
  • Updated/expanded registry auth tests and adjusted LLM tests to reflect the extraction.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/registry/auth/oauth_token_source.go Removed duplicated registry-specific OAuth token source implementation.
pkg/registry/auth/auth.go Replaced registry token source construction with tokensource.New(...) and centralized config persistence.
pkg/registry/auth/auth_test.go Reworked tests to validate behavior via the public API and new shared behavior (persisting rotated RTs).
pkg/registry/auth/helpers_test.go Added OIDC discovery test server helper for registry auth tests.
pkg/llm/tokensource.go Replaced LLM token source implementation with a thin wrapper around tokensource.OAuthTokenSource.
pkg/llm/tokensource_test.go Trimmed old LLM-specific tests; added a smaller set aligned with shared implementation.
pkg/auth/tokensource/tokensource.go New shared OAuth/OIDC token source implementation used by both LLM and registry.
pkg/auth/tokensource/tokensource_test.go New black-box tests covering tiering, caching, key provider, and config persistence behavior.
pkg/auth/tokensource/preemptive_test.go New internal regression tests for preemptive refresh composition behavior.
pkg/auth/tokensource/doc.go New package documentation for the shared token source.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/auth/tokensource/tokensource.go
Comment thread pkg/auth/tokensource/tokensource.go Outdated
Comment thread pkg/llm/tokensource_test.go Outdated
Comment thread pkg/llm/tokensource_test.go Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

❌ Patch coverage is 81.85841% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.01%. Comparing base (3af3847) to head (278a22e).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
pkg/auth/tokensource/tokensource.go 80.85% 34 Missing and 2 partials ⚠️
pkg/registry/auth/auth.go 78.26% 4 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5090      +/-   ##
==========================================
+ Coverage   66.92%   67.01%   +0.09%     
==========================================
  Files         595      595              
  Lines       60080    59994      -86     
==========================================
- Hits        40208    40205       -3     
+ Misses      16807    16729      -78     
+ Partials     3065     3060       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@yrobla yrobla requested a review from Copilot April 28, 2026 13:37
@github-actions github-actions Bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 28, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/auth/tokensource/tokensource.go Outdated
Comment thread pkg/auth/tokensource/tokensource.go Outdated
Comment thread pkg/auth/tokensource/tokensource.go
Comment thread pkg/registry/auth/auth.go Outdated
@yrobla yrobla requested a review from Copilot April 28, 2026 13:52
@github-actions github-actions Bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 28, 2026
@github-actions github-actions Bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 28, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/auth/tokensource/tokensource_test.go Outdated
Comment thread pkg/auth/tokensource/tokensource.go Outdated
Both pkg/llm and pkg/registry/auth implemented the same three-tier
OAuth token strategy (in-memory cache → secrets-cached access token →
refresh token → browser OIDC/PKCE). This extracts that logic into a
single shared package, pkg/auth/tokensource, and rewires both consumers
as thin wrappers.

As a side effect, the registry path now wraps its restored token source
with PersistingTokenSource, matching the LLM path and ensuring rotated
refresh tokens are re-persisted after a cache restore.

Closes #5050
@yrobla yrobla requested a review from Copilot April 28, 2026 14:55
@github-actions github-actions Bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 28, 2026
@github-actions github-actions Bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 28, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/auth/tokensource/tokensource.go
Comment thread pkg/auth/tokensource/tokensource.go
@github-actions github-actions Bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 28, 2026
Copy link
Copy Markdown
Member

@aponcedeleonch aponcedeleonch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three small follow-ups inline. Nice refactor overall.

Comment thread pkg/auth/tokensource/tokensource.go
Comment thread pkg/registry/auth/auth_test.go Outdated
Comment thread pkg/auth/tokensource/tokensource_test.go Outdated
@github-actions github-actions Bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Apr 29, 2026
Copy link
Copy Markdown
Member

@aponcedeleonch aponcedeleonch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clean refactor. All three of my comments are addressed. The regression surface looks tight: LLM is a pure extraction, registry's behavior changes are intentional and well-tested. LGTM.

@yrobla yrobla merged commit 9c66743 into main Apr 29, 2026
43 checks passed
@yrobla yrobla deleted the issue-5050 branch April 29, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Extra large PR: 1000+ lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract shared OAuthTokenSource from pkg/registry/auth and pkg/llm

4 participants