All posts
ENGINEERINGPRODUCT

How Syncore Keeps Your OAuth Tokens Fresh Without You Lifting a Finger

Syncore Engineering·March 18, 2026·6 min read

The Problem: Silent Token Expiry

OAuth access tokens expire. Google tokens expire after 1 hour. Slack tokens can expire after 12 hours. When a token expires mid-task, your AI agent gets a 401 Unauthorized error, the tool call fails, and the agent either halts or produces a confusing error message.

The naive fix is to refresh the token when the error happens. The problem: by the time the agent sees the 401, it's already in the middle of a multi-step task. Recovering from a mid-task auth failure is hard — the agent may have already taken actions that can't be undone.

Syncore's approach is different: refresh tokens *proactively*, before they expire, so the agent never encounters a stale credential in the first place.

How the Token Keeper Works

When the Syncore daemon starts, it spawns a background goroutine called the token keeper. It runs a keep-alive cycle on a fixed interval and handles three layers of credential freshness:

Layer 1: Supabase session (your Syncore login)

The daemon checks whether your Supabase refresh token is within 15 minutes of expiry. If so, it calls the Supabase token refresh endpoint and writes the new session to disk. If the refresh token itself has permanently expired (session older than the max refresh window), the daemon logs a warning and sets a flag so the CLI can surface a clear syncore login prompt — no cryptic 401s.

Layer 2: Provider OAuth tokens (Gmail, Slack, Notion, etc.)

Every 5 minutes, the daemon iterates over all stored OAuth tokens and checks each one's expires_at field. Any token within 10 minutes of expiry gets refreshed immediately by calling the Syncore vault API, which handles the provider-specific refresh grant flow. The refreshed token is written back to disk encrypted.

Token keeper cycle (every 5 minutes):
  ├── Check Supabase session expiry (buffer: 15 min)
  │     └── If expiring → refresh via Supabase token endpoint
  ├── For each OAuth provider token:
  │     └── If expires_at < now + 10 min → refresh via vault API
  └── Full vault sync (throttled to every 30 minutes)

Layer 3: Periodic vault sync

Every 30 minutes, the daemon does a full pull from the Syncore vault. This catches any credentials updated from another device (e.g., you re-authorized Gmail on your laptop, and now your desktop picks up the new tokens automatically).

What Happens at Tool Call Time

When your AI agent invokes a Syncore tool — say, gmail__search_emails — the daemon spawns the Gmail skill process and injects the current access token as an environment variable just before execution:

GMAIL_ACCESS_TOKEN=ya29.current-fresh-token  # injected by daemon
GMAIL_REFRESH_TOKEN=1//...                   # injected by daemon
SYNCORE_USER_JWT=eyJ...                      # injected by daemon

The skill process reads these variables and calls the Gmail API. It never touches the credential store itself. It never needs to implement refresh logic. By the time the skill runs, the daemon has already ensured the token is fresh.

Recovery from Permanent Expiry

If a provider token can't be refreshed — the user revoked access, the OAuth app was deleted, the refresh token itself expired — the daemon marks that provider as requiring re-authorization and surfaces a clear error:

Authentication failed for gmail. The token may be expired or revoked.
Fix: re-authorize at https://syncorelabs.ai/connect, then run `syncore update` to sync.

This message appears in the tool call result returned to the AI agent, so the agent can surface it to the user with a clear next step rather than a generic failure.

The Result

In practice, developers using Syncore never think about OAuth tokens. The daemon handles expiry silently in the background. The only time you see an auth message is when a token has been permanently revoked and genuinely needs human action — and even then, the fix is one URL visit and one CLI command.

Try Syncore for free

Connect 50+ tools to Claude, Cursor, and Windsurf in under 5 minutes. No API keys required to get started.

Get Started Free
$curl -fsSL https://syncorelabs.ai/install.sh | sh