Skip to content

feat: refresh expiring OAuth tokens before dispatch - #26

Merged
shreyanshjain7174 merged 1 commit into
mainfrom
feat/refresh-expiring-oauth-tokens
Aug 29, 2026
Merged

feat: refresh expiring OAuth tokens before dispatch#26
shreyanshjain7174 merged 1 commit into
mainfrom
feat/refresh-expiring-oauth-tokens

Conversation

@shreyanshjain7174

Copy link
Copy Markdown
Contributor

What changed:

  • Refreshes configured OAuth tokens that expire within 5 minutes before upstream dispatch.
  • Reuses one token-exchange parser for authorization-code and refresh-token grants.
  • Persists refreshed and rotated tokens through the existing encrypted vault.
  • Blocks upstream dispatch and records token_expired when refresh fails.

Verification:

  • go test ./internal/gateway -run TestAct_RefreshesExpiringTokenBeforeDispatch -count=1
  • go test ./internal/oauth -run TestNewRefreshFuncExchangesAndRotatesToken -count=1
  • go test ./... -race -count=1
  • go vet ./...

All passed locally.

Signed-off-by: Shreyansh Sancheti <43677304+shreyanshjain7174@users.noreply.github.com>
@shreyanshjain7174
shreyanshjain7174 requested a lite review from Copilot August 29, 2026 16:42
@shreyanshjain7174
shreyanshjain7174 merged commit bb80706 into main Aug 29, 2026
2 checks passed
@shreyanshjain7174
shreyanshjain7174 deleted the feat/refresh-expiring-oauth-tokens branch August 29, 2026 16:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds automatic OAuth token refresh to the gateway dispatch path. It refreshes tokens that expire within 5 minutes, updates the encrypted vault, and blocks upstream calls when refresh fails.

Changes:

  • Refresh expiring OAuth tokens before upstream dispatch via per-service refresh functions.
  • Reuse a shared token-exchange parser for both auth-code and refresh-token flows.
  • Add tests covering refresh success, rotation persistence, and refresh failure blocking.

Reviewed changes

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

Show a summary per file
File Description
README.md Documents pre-dispatch OAuth refresh behavior and failure semantics.
internal/oauth/refresh_test.go Adds a unit test for the refresh-token exchange and rotation behavior.
internal/oauth/handler.go Introduces NewRefreshFunc and refactors token exchange parsing for reuse.
internal/gateway/gateway.go Hooks token refresh into /v1/act execution before upstream requests.
internal/gateway/gateway_test.go Adds integration tests ensuring refresh happens and failures are receipted.
cmd/agentgw/main.go Wires configured OAuth providers into gateway refreshers at startup.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +403 to +412
if refresher := s.cfg.Refreshers[att.req.Service]; refresher != nil {
tok, err = vault.GetOrRefresh(s.cfg.Vault, att.req.OnBehalfOf, att.req.Service, refresher)
if err != nil {
return &outcome{
status: http.StatusForbidden,
body: ErrorResponse{Error: "token expired — user must re-authenticate", Code: "token_expired"},
policyDecision: "allow",
errorCode: "token_expired",
}
}
Comment thread internal/oauth/handler.go
Comment on lines +178 to 182
func exchangeToken(provider *Provider, data url.Values) (*vault.Token, time.Duration, error) {
resp, err := http.PostForm(provider.TokenURL, data)
if err != nil {
return nil, fmt.Errorf("oauth: exchange: %w", err)
return nil, 0, fmt.Errorf("oauth: exchange: %w", err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants