Skip to content

fix(control-plane): refresh runner tokens immediately on startup#1207

Merged
markturansky merged 2 commits intoalphafrom
fix/cp-token-refresh-loop
Apr 4, 2026
Merged

fix(control-plane): refresh runner tokens immediately on startup#1207
markturansky merged 2 commits intoalphafrom
fix/cp-token-refresh-loop

Conversation

@markturansky
Copy link
Copy Markdown
Contributor

@markturansky markturansky commented Apr 4, 2026

Summary

  • The token refresh loop fires every 10 minutes via a ticker
  • If the control-plane restarts while sessions are running, the ticker resets and won't fire for another 10 minutes
  • OIDC BOT_TOKENs have a ~15 min TTL — a runner pod started near end-of-token-life can expire before the first post-restart tick
  • Fix: call refreshAllRunningTokens once immediately on goroutine start before entering the ticker loop

Test plan

  • Restart control-plane while a session is running
  • Verify "runner token refreshed" log appears within seconds of pod start
  • Verify runner does not get UNAUTHENTICATED on gRPC after control-plane restart

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Token refresh now triggers immediately upon startup before entering periodic refresh cycles, improving responsiveness.
    • Token refresh scope expanded to include all projects, ensuring tokens are refreshed across the entire system.

Ambient Code Bot and others added 2 commits April 3, 2026 21:27
refreshAllRunningTokens called ForProject(ctx, "") which the SDK
rejects with "project is required". Sessions are project-scoped so
the cross-project list requires iterating all projects first, then
listing running sessions per project.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
The token refresh ticker fires every 10 minutes. If the control-plane
restarts during an active session, existing runner BOT_TOKENs can
expire before the first ticker tick fires. Trigger an immediate refresh
on startup so any in-flight sessions get fresh tokens right away.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 4, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

The token refresh mechanism in the Kubernetes reconciler is enhanced to execute an immediate refresh upon startup and expanded to refresh tokens across all projects instead of a single project, with refined error handling for per-project failures.

Changes

Cohort / File(s) Summary
Token Refresh Enhancement
components/ambient-control-plane/internal/reconciler/kube_reconciler.go
Modified StartTokenRefreshLoop to trigger immediate refreshAllRunningTokens call before starting the periodic ticker. Refactored refreshAllRunningTokens to paginate across all projects via Projects().List, then list running sessions per project with pagination. Error handling changed: project-list failures halt execution; per-project SDK failures skip to next project; per-page session failures break iteration for that project only.

Sequence Diagram(s)

sequenceDiagram
    participant Reconciler
    participant Ticker as Ticker/Scheduler
    participant ProjectsAPI as Projects API
    participant SessionsAPI as Sessions API

    Reconciler->>Reconciler: StartTokenRefreshLoop()
    activate Reconciler
    
    Reconciler->>Reconciler: refreshAllRunningTokens(ctx) - Immediate
    activate Reconciler
    Reconciler->>ProjectsAPI: List all projects (paginated)
    activate ProjectsAPI
    ProjectsAPI-->>Reconciler: Projects batch
    deactivate ProjectsAPI
    
    loop For each project
        Reconciler->>Reconciler: Create SDK client
        Reconciler->>SessionsAPI: List running sessions (paginated)
        activate SessionsAPI
        SessionsAPI-->>Reconciler: Sessions batch
        deactivate SessionsAPI
        Reconciler->>Reconciler: Process/refresh tokens
    end
    deactivate Reconciler
    
    Reconciler->>Ticker: Start periodic ticker
    activate Ticker
    
    loop On each tick
        Ticker->>Reconciler: Trigger refresh
        Reconciler->>Reconciler: refreshAllRunningTokens(ctx)
        note over Reconciler: Same project iteration logic
    end
    deactivate Ticker
    deactivate Reconciler
Loading
🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows Conventional Commits format (fix scope): description and directly addresses the main change - immediate token refresh on startup.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Performance And Algorithmic Complexity ✅ Passed Pagination (size 100) properly implemented with correct termination logic. O(P × S) complexity acceptable for 10-minute refresh cycle. Pre-existing SDK cache not introduced by PR.
Security And Secret Handling ✅ Passed PR introduces no blocking security violations. Tokens properly encrypted in K8s secrets, never logged plaintext. All search queries hardcoded with no injection vectors. Auth/authz correctly delegated via factory pattern.
Kubernetes Resource Safety ✅ Passed PR modifies only Go logic in token refresh reconciler with no Kubernetes manifest, RBAC, resource limit, or pod security context changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cp-token-refresh-loop
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/cp-token-refresh-loop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@markturansky markturansky merged commit 8526929 into alpha Apr 4, 2026
34 of 36 checks passed
@markturansky markturansky deleted the fix/cp-token-refresh-loop branch April 4, 2026 02:02
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.

1 participant