How OpenSEO Handles Scheduled Jobs for OAuth and Audits

OpenSEO leverages Cloudflare Workers' native Cron triggers for periodic site audits while handling OAuth token refreshes on-demand through a dedicated token endpoint that enforces a 30-day TTL, implemented across the oauth-provider and audit workflow files.

OpenSEO is an open-source SEO platform designed for edge deployment on Cloudflare Workers. Its architecture separates time-sensitive audit workflows from authentication lifecycle management, using distinct patterns for scheduled execution versus token refresh orchestration.

OAuth Token Refresh Architecture

Unlike traditional cron-based refresh mechanisms, OpenSEO implements an on-demand token rotation strategy within its OAuth provider. When an access token expires, the consumer initiates a refresh request that validates, rotates, and persists new credentials atomically.

Token Endpoint and TTL Management

The OAuth provider logic resides in src/server/mcp/oauth-provider.ts. This file defines the token endpoint handling for grant_type=refresh_token requests and enforces the MCP_REFRESH_TOKEN_TTL_SECONDS constant, which sets a 30-day lifespan for refresh tokens.

When a refresh request arrives, the provider validates the existing token against its TTL, generates a new access token, and conditionally rotates the refresh token if the current one approaches expiration. This approach eliminates the need for background scheduled jobs to maintain token freshness while ensuring credentials never exceed their maximum age.

Secure Token Persistence

Refresh tokens are encrypted and stored via the self-hosted Google OAuth implementation in src/server/features/google/selfHostedOAuth.ts. This module persists the rotated refresh tokens securely between refresh cycles, ensuring that subsequent authentication requests can retrieve valid credentials without user intervention.

Scheduled Site Audit Workflows

Site audits run on true scheduled intervals using Cloudflare Workers' ExportedHandlerScheduledHandler interface. The platform defines these triggers in type declarations and implements the execution logic in dedicated workflow modules.

Cron Configuration in Worker Definitions

The worker-configuration.d.ts file declares the scheduled handler interface for the auxiliary audit worker. This configuration exposes the Cron trigger to the Cloudflare runtime, allowing the platform to invoke the audit workflow at defined intervals without external scheduling services.

SiteAuditWorkflow Orchestration

The actual audit execution is managed by src/server/features/rank-tracking/services/scheduledRankChecks.ts and similar workflow modules like src/server/workflows/siteAuditWorkflowPhases.ts. When the Cron trigger fires, the scheduled handler extracts pending audit configurations and invokes SiteAuditWorkflow.run().

This workflow orchestrates a multi-phase process including site crawling, Lighthouse performance analysis, and result persistence through the AuditRepository. The pattern demonstrated in scheduledRankChecks.ts shows how the platform retrieves pending jobs, iterates through audit IDs, and launches workflow instances with payloads containing auditId, origin, startUrl, and maxPages.

Implementation Examples

The following patterns illustrate how OpenSEO handles both OAuth refreshes and scheduled audits.

Refreshing an OAuth token on-demand:

// Client-side refresh request to OpenSEO's OAuth endpoint
const response = await fetch(
  `${BASE_URL}/mcp/oauth/token`,
  {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "refresh_token",
      refresh_token: storedRefreshToken,
      client_id: CLIENT_ID,
    }),
  }
);
const { access_token, refresh_token } = await response.json();

Scheduled audit handler in the worker:

// Defined in the audit worker's scheduled handler
export const scheduled: ExportedHandlerScheduledHandler<Env> = async (controller) => {
  const pending = await AuditService.getPendingAudits();
  
  for (const audit of pending) {
    await SiteAuditWorkflow.run({
      auditId: audit.id,
      origin: audit.origin,
      startUrl: audit.startUrl,
      maxPages: audit.maxPages,
    });
  }
};

Launching rank-checking jobs using the same pattern:

// Pattern from scheduledRankChecks.ts
import { runScheduledRankChecks } from "@/server/features/rank-tracking/services/scheduledRankChecks";

export const scheduled: ExportedHandlerScheduledHandler<Env> = async () => {
  await runScheduledRankChecks();
};

Summary

  • On-Demand OAuth: OpenSEO refreshes Google OAuth tokens via the grant_type=refresh_token endpoint in src/server/mcp/oauth-provider.ts rather than using cron jobs, utilizing a 30-day TTL and secure storage in selfHostedOAuth.ts.
  • Cron-Based Audits: Site audits execute through Cloudflare Workers' ExportedHandlerScheduledHandler declared in worker-configuration.d.ts, triggering SiteAuditWorkflow.run() orchestrated in the workflow phases module.
  • Workflow Pattern: The platform handles scheduled jobs by retrieving pending configurations and dispatching them to typed workflow runners, as demonstrated in the rank-tracking service implementation.

Frequently Asked Questions

Does OpenSEO use a cron job to refresh OAuth tokens?

No. OpenSEO handles OAuth token refreshes on-demand through the token endpoint defined in src/server/mcp/oauth-provider.ts. When a client requests a refresh, the provider validates the existing token, checks its TTL, and returns new credentials without requiring a background scheduled process.

How are refresh tokens stored securely between refreshes?

The src/server/features/google/selfHostedOAuth.ts module encrypts and persists refresh tokens in the Cloudflare Workers KV or similar storage. This ensures that tokens remain available for subsequent on-demand refreshes while maintaining encryption at rest.

What triggers the SiteAuditWorkflow to run?

The workflow triggers via Cloudflare's Cron mechanism through the scheduled handler exported in the audit worker configuration. When the Cron interval specified in worker-configuration.d.ts elapses, the handler invokes SiteAuditWorkflow.run() with the appropriate audit parameters.

Where is the scheduled job handler configured for rank tracking?

The pattern is implemented in src/server/features/rank-tracking/services/scheduledRankChecks.ts, which provides a runScheduledRankChecks() function called by the worker's scheduled export. This follows the same architectural pattern as site audits, retrieving pending configurations and dispatching them to workflow runners.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →