How to Connect and Authenticate Google Search Console in OpenSEO
OpenSEO authenticates Google Search Console through an OAuth 2.0 flow that stores grants in a gsc_grants table and automatically handles token refresh and reconnection.
Connecting your Google Search Console account to OpenSEO enables the platform to pull search analytics, inspect URL indexing status, and monitor site performance directly within your dashboard. This integration relies on a secure, standards-compliant OAuth 2.0 implementation that the OpenSEO team built into their generic authentication layer.
OAuth Provider Configuration
The GSC integration starts with provider registration in src/shared/gsc.ts. This file defines the unique provider identifier and the specific Google API scopes required for read-only access:
// src/shared/gsc.ts
export const GSC_OAUTH_PROVIDER_ID = "google-search-console";
export const GSC_OAUTH_SCOPES = [
"https://www.googleapis.com/auth/webmasters.readonly",
];
These constants get referenced across the codebase whenever GSC-specific OAuth operations occur.
The global authentication configuration in src/lib/auth-config.ts registers this provider so the OAuth engine knows which scopes and redirect URLs to apply:
// Inside the OAuth providers array in src/lib/auth-config.ts
{
providerId: GSC_OAUTH_PROVIDER_ID, // line 41
}
This registration happens once at application startup and enables all subsequent GSC linking flows.
Initiating the Connection Flow
When a user clicks Connect Google Search Console, the client-side code in src/client/features/integrations/startGoogleLink.ts handles the handoff to Google's consent screen:
// Client-side initiation
import { startGoogleLink } from '@/client/features/integrations/startGoogleLink';
// Called from a button click
await startGoogleLink({ integration: 'gsc' });
The startGoogleLink function forwards GSC_OAUTH_PROVIDER_ID to the generic startOAuthLink helper, which redirects the user to Google's OAuth consent screen with the exact scopes defined in src/shared/gsc.ts.
Callback Handling and Token Storage
After the user grants permission, Google redirects back to OpenSEO's OAuth callback endpoint. According to the source code in every-app/open-seo, this callback:
- Creates a grant linked to the authenticated user
- Stores the grant in the
gsc_grantsdatabase table - Associates the grant with
providerId: "google-search-console"
This grant persists the refresh token and expiration metadata needed for subsequent API calls without requiring repeated user consent.
Service Layer: GscService
The src/server/features/gsc/services/GscService.ts file orchestrates all GSC interactions. It reads the user's stored grant and creates a GscClient instance:
// GscService retrieves the grant using the provider ID
providerId: GSC_OAUTH_PROVIDER_ID // line 41
GscService validates connections on every request and automatically detects expired or revoked tokens (lines 83 and 128). When a token fails validation, it surfaces a reconnect UI rather than throwing raw errors—this graceful degradation keeps the user experience smooth.
Key methods exposed by GscService:
searchAnalytics– Query search performance data with dimensions and filtersinspectUrls– Check URL indexing status and coverage issuesdisconnect– Remove the stored grant and revoke server-side tokens
Low-Level API Client
The src/server/lib/gscClient.ts file builds the authenticated HTTP client that talks directly to Google's Search Console API. When constructing a client, it passes the provider ID to ensure the correct grant gets loaded:
// src/server/lib/gscClient.ts, line 96
const client = createGscClient({
userId,
gscAccountId,
providerId: GSC_OAUTH_PROVIDER_ID
});
This client handles request signing, quota management, and standardized error responses that GscService can interpret.
Server-Function API
The public interface for the UI lives in src/serverFunctions/gsc.ts. This file exposes functions that:
- Return connection state (
googleOAuthConfigured) - Allow property selection from available GSC sites
- Trigger disconnect or reconnect flows
Key implementation details include provider selection at line 73 and disconnect event handling at line 124.
Querying Search Console Data
Once authenticated, your server functions can query analytics data through GscService:
import { GscService } from '@/server/features/gsc/services/GscService';
import { SearchAnalyticsRequest } from '@/server/lib/gscClient';
export async function getSearchPerformance(
projectId: string,
request: SearchAnalyticsRequest
) {
// GscService pulls the stored grant, refreshes tokens if needed
const rows = await GscService.searchAnalytics({ projectId, request });
return rows; // array of GscSearchAnalyticsRow
}
To disconnect a property:
import { GscService } from '@/server/features/gsc/services/GscService';
await GscService.disconnect({ userId: currentUser.id, projectId });
Error Handling
GSC-specific errors like GscNotConnectedError and token revocation scenarios are defined in src/server/lib/gscErrors.ts. The MCP tooling in src/server/mcp/tools/search-console-tools.ts translates these into friendly UI messages, with the specific reason code gsc_oauth_not_configured returned at line 86 when authentication is missing or invalid.
This layered error handling ensures users see actionable messages like "Reconnect Google Search Console" rather than cryptic OAuth failures.
Complete File Reference
| File | Purpose |
|---|---|
src/shared/gsc.ts |
Provider ID and OAuth scope constants |
src/lib/auth-config.ts |
Global OAuth provider registration |
src/client/features/integrations/startGoogleLink.ts |
Client-side link initiation |
src/server/lib/gscClient.ts |
Low-level authenticated HTTP client |
src/server/features/gsc/services/GscService.ts |
Core service for connection management and API calls |
src/serverFunctions/gsc.ts |
Public server-function API |
src/server/lib/gscErrors.ts |
GSC-specific error definitions |
src/server/mcp/tools/search-console-tools.ts |
Error translation for UI |
Summary
- Provider registration in
src/shared/gsc.tsdefines the OAuth identity and read-only scopes for Google Search Console - Client-side initiation via
startGoogleLinkredirects users through Google's consent flow - Grant storage persists tokens in
gsc_grantswith automatic refresh handled byGscService - Service layer in
GscService.tsvalidates connections, detects revocation, and exposessearchAnalyticsandinspectUrlsmethods - Error handling surfaces reconnect prompts rather than raw OAuth failures, maintaining UX quality
Frequently Asked Questions
What permissions does OpenSEO request from Google Search Console?
OpenSEO requests the https://www.googleapis.com/auth/webmasters.readonly scope, which provides read-only access to search analytics, URL inspection data, and site coverage information. The platform cannot modify your site configuration or submit URLs for indexing with this scope alone.
How does OpenSEO handle expired or revoked tokens?
The GscService class validates tokens before every API call and automatically detects expiration or revocation at lines 83 and 128 of src/server/features/gsc/services/GscService.ts. When detection occurs, it returns a state that triggers a reconnect UI rather than failing the request—users simply click to re-authenticate without losing their configuration.
Can I connect multiple Google Search Console properties to one OpenSEO project?
Yes. The gsc_grants table stores grants per user, and GscService supports selecting from multiple available properties through the server-function API in src/serverFunctions/gsc.ts. The UI can present all properties the authenticated Google account has access to, letting users choose which to associate with each project.
Where is the OAuth client secret stored in OpenSEO?
The analysis shows provider configuration in src/shared/gsc.ts and src/lib/auth-config.ts, but client secrets for the OAuth application are handled at the infrastructure level within OpenSEO's deployment environment— they do not appear in the referenced source files. This follows security best practices of keeping secrets out of version control and using environment-specific secret management.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →