OAuth Setup with Claude Code (2026)
The Pattern
Pre-stage OAuth configuration details (provider URLs, scopes, token formats, error codes) in a skill file so Claude Code implements the flow correctly on the first attempt, instead of entering expensive trial-and-error debugging loops that waste 30,000-80,000 tokens.
Why It Matters for Token Cost
OAuth implementation is a top-5 token-expensive task for Claude Code. The protocol involves multiple HTTP endpoints, redirect flows, token exchange, refresh logic, and provider-specific quirks. Without pre-staged configuration, Claude Code typically:
- Reads OAuth library documentation (~2,000-4,000 tokens)
- Implements a first attempt (~3,000-5,000 tokens)
- Encounters an error (wrong redirect URI, missing scope, bad token format) (~1,000 tokens)
- Debugs the error (~5,000-10,000 tokens: reads logs, searches docs, tries fixes)
- Repeats steps 3-4 two to three times (~10,000-30,000 tokens)
Total: 30,000-80,000 tokens for a flow that a pre-staged implementation completes in 10,000-15,000 tokens. At Sonnet 4.6 rates ($3/$15 per MTok), the difference is $0.09-$0.96 per OAuth implementation task.
The Anti-Pattern (What NOT to Do)
# Anti-pattern: vague OAuth prompt with no pre-staged config
claude -p "Add Google OAuth login to the app"
# Claude Code proceeds to:
# 1. Search for OAuth libraries (Grep, 2 calls, ~500 tokens)
# 2. Read passport-google-oauth20 docs (WebFetch, ~3,000 tokens)
# 3. Implement with guessed config (~5,000 tokens)
# 4. Hit "redirect_uri_mismatch" error (~2,000 tokens debugging)
# 5. Fix redirect URI (~3,000 tokens)
# 6. Hit "invalid_scope" error (~2,000 tokens debugging)
# 7. Fix scopes (~2,000 tokens)
# 8. Hit token parsing error (~3,000 tokens debugging)
# Total: ~23,000 tokens just in tool calls, before counting model reasoning
The Pattern in Action
Step 1: Create an OAuth Configuration Skill
# .claude/skills/oauth-google.md
# Google OAuth 2.0 Configuration
# Provider Details
# Auth URL: https://accounts.google.com/o/oauth2/v2/auth
# Token URL: https://oauth2.googleapis.com/token
# UserInfo URL: https://www.googleapis.com/oauth2/v2/userinfo
# Scopes: openid email profile
# Environment Variables (must be set before implementation)
# GOOGLE_CLIENT_ID: from Google Cloud Console > APIs & Services > Credentials
# GOOGLE_CLIENT_SECRET: same location
# GOOGLE_REDIRECT_URI: must EXACTLY match console setting (including trailing slash)
# Common Errors and Fixes
# redirect_uri_mismatch: ensure GOOGLE_REDIRECT_URI matches console exactly
# invalid_scope: use space-separated scopes, not comma-separated
# invalid_grant: authorization code was already used or expired (10 min lifetime)
# Implementation Pattern (Express + Passport)
# 1. Install: pnpm add passport passport-google-oauth20 express-session
# 2. Configure passport strategy with client ID, secret, callback URL
# 3. Add routes: /auth/google (redirect) and /auth/google/callback (handler)
# 4. Store user in session after successful auth
# 5. Add session middleware BEFORE passport middleware
# Token Response Fields:
# access_token, expires_in (3599), refresh_token, scope, token_type, id_token
Step 2: Pre-Stage Environment
# Verify environment variables before starting Claude Code
echo "GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:?'Not set - configure first'}"
echo "GOOGLE_REDIRECT_URI: ${GOOGLE_REDIRECT_URI:?'Not set - configure first'}"
echo "Session secret: ${SESSION_SECRET:?'Not set - generate with openssl rand -hex 32'}"
Step 3: Scoped Prompt with Skill Reference
claude --max-turns 15 -p "Implement Google OAuth login following the oauth-google skill.
Use passport-google-oauth20 with Express.
Store the authenticated user in the session.
Add routes at /auth/google and /auth/google/callback.
Environment variables are already configured."
With the skill providing all configuration details, Claude Code implements correctly on the first attempt in most cases: ~10,000-15,000 tokens instead of 30,000-80,000.
Before and After
| Metric | Without Skill | With OAuth Skill | Savings |
|---|---|---|---|
| Implementation tokens | 10,000-15,000 | 8,000-12,000 | 20-25% |
| Debug/retry tokens | 20,000-65,000 | 2,000-5,000 | 85-92% |
| Total tokens | 30,000-80,000 | 10,000-17,000 | 67-79% |
| Tool calls | 15-25 | 5-10 | 50-67% |
| Cost (Sonnet 4.6) | $0.09-$0.96 | $0.03-$0.20 | $0.06-$0.76 |
The Broader Principle: Pre-Stage Complex Integrations
OAuth is the most common example, but the same pattern applies to any complex integration:
# .claude/skills/stripe-setup.md
## Stripe Integration Configuration
- API version: 2024-12-18.acacia
- Webhook endpoint: /api/webhooks/stripe
- Webhook secret: STRIPE_WEBHOOK_SECRET env var
- Event types to handle: checkout.session.completed, customer.subscription.updated, invoice.payment_failed
- Test mode: use STRIPE_SECRET_KEY_TEST, production: STRIPE_SECRET_KEY
- Common error: "No signatures found matching the expected signature" means webhook secret mismatch
# .claude/skills/aws-s3-setup.md
## S3 Upload Configuration
- Bucket: UPLOAD_BUCKET env var
- Region: us-east-1
- IAM: use instance role, not access keys
- Presigned URL expiry: 3600 seconds
- Max file size: 10MB (enforced client-side and in S3 policy)
- CORS: must be configured on the bucket for browser uploads
- Common error: "AccessDenied" usually means IAM policy missing s3:PutObject for the path prefix
Each of these skills prevents 5,000-20,000 tokens of trial-and-error debugging by providing the exact configuration that works. The pattern is: any integration with provider-specific quirks, error codes, or configuration gotchas benefits from a pre-staged skill file.
Total savings across all integrations: 20,000-80,000 tokens per project setup sprint ($0.06-$0.96 on Sonnet 4.6)
When to Use This Pattern
- Any third-party OAuth integration: Google, GitHub, Microsoft, Apple – all have provider-specific quirks that cause expensive debugging.
- Team projects: Pre-stage the OAuth skill once, and every developer benefits from zero-retry implementations.
- Multiple auth providers: Create one skill file per provider. The upfront investment pays back on every implementation.
Multi-Provider OAuth Template
For applications supporting multiple OAuth providers, create a template skill that standardizes the implementation pattern:
# .claude/skills/oauth-template.md
## OAuth Provider Template
### Required Files per Provider
1. `src/auth/providers/{provider}.ts` -- strategy configuration
2. `src/auth/callbacks/{provider}.ts` -- callback handler
3. `.env` entries: `{PROVIDER}_CLIENT_ID`, `{PROVIDER}_CLIENT_SECRET`, `{PROVIDER}_REDIRECT_URI`
### Implementation Checklist
- [ ] Install passport strategy: `pnpm add passport-{provider}-oauth20`
- [ ] Create strategy file with client ID, secret, callback URL
- [ ] Add routes: `/auth/{provider}` (redirect) and `/auth/{provider}/callback`
- [ ] Handle user creation/linking in callback (findOrCreate pattern)
- [ ] Add session serialization if not already configured
- [ ] Test with `curl -v http://localhost:3000/auth/{provider}` (should redirect to provider)
### Error Handling Checklist
- [ ] Handle "access_denied" (user clicked cancel)
- [ ] Handle "invalid_grant" (code expired, retry)
- [ ] Handle "redirect_uri_mismatch" (check console settings)
- [ ] Handle rate limiting from the provider
- [ ] Log all OAuth errors with provider name and error code
This template skill (~300 tokens) prevents repeated trial-and-error across multiple providers. Without it, each new OAuth provider integration goes through the same expensive discovery cycle. With it, the second and third providers cost 50-70% less to implement than the first.
Testing OAuth Without Real Providers
Pre-stage a testing approach to avoid token-expensive debugging against live OAuth endpoints:
# scripts/test-oauth-flow.sh
# Verify OAuth configuration without hitting real providers
set -euo pipefail
echo "=== OAuth Configuration Test ==="
# Check environment variables
for PROVIDER in GOOGLE GITHUB; do
CLIENT_ID_VAR="${PROVIDER}_CLIENT_ID"
SECRET_VAR="${PROVIDER}_CLIENT_SECRET"
REDIRECT_VAR="${PROVIDER}_REDIRECT_URI"
if [ -z "${!CLIENT_ID_VAR:-}" ]; then
echo "FAIL: ${CLIENT_ID_VAR} not set"
else
echo "PASS: ${CLIENT_ID_VAR} is set (${#!CLIENT_ID_VAR} chars)"
fi
if [ -z "${!SECRET_VAR:-}" ]; then
echo "FAIL: ${SECRET_VAR} not set"
else
echo "PASS: ${SECRET_VAR} is set"
fi
if [ -z "${!REDIRECT_VAR:-}" ]; then
echo "FAIL: ${REDIRECT_VAR} not set"
else
echo "PASS: ${REDIRECT_VAR} = ${!REDIRECT_VAR}"
# Check for common mistakes
if echo "${!REDIRECT_VAR}" | grep -q "localhost" && echo "${!REDIRECT_VAR}" | grep -q "https"; then
echo "WARN: localhost with https -- most providers reject this"
fi
fi
echo ""
done
# Test that auth routes are registered
echo "=== Route Check ==="
for PROVIDER in google github; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:3000/auth/$PROVIDER" 2>/dev/null)
if [ "$STATUS" = "302" ]; then
echo "PASS: /auth/$PROVIDER redirects (302)"
else
echo "FAIL: /auth/$PROVIDER returned $STATUS (expected 302)"
fi
done
Running this verification script (one Bash call, ~245 tokens) catches configuration errors that would otherwise take 3-5 debug cycles (1,500-3,000 tokens each) to discover.
When NOT to Use This Pattern
- Simple API key authentication: OAuth skills are overkill for API-key-based auth. A CLAUDE.md note is sufficient.
- Pre-built auth platforms: If using Auth0, Clerk, or Supabase Auth, their SDKs handle the OAuth complexity. A simpler skill file listing the SDK methods is more appropriate.
Implementation in CLAUDE.md
# CLAUDE.md -- OAuth Rule
## Authentication
- OAuth configuration: see oauth-google skill (or oauth-github, etc.)
- ALWAYS read the provider-specific skill before implementing OAuth
- Verify environment variables are set before writing code
- Common OAuth errors and fixes are listed in the skill -- check there before debugging
- Never hardcode OAuth credentials -- always use environment variables
Cost Comparison: With vs Without OAuth Skills
| Implementation Phase | Without Skills (tokens) | With Skills (tokens) | Savings |
|---|---|---|---|
| First provider setup | 25,000-45,000 | 10,000-20,000 | 50-55% |
| Second provider setup | 20,000-35,000 | 5,000-10,000 | 70-75% |
| Debug redirect errors | 5,000-15,000 | 1,000-3,000 | 80% |
| Total (2 providers) | 50,000-95,000 | 16,000-33,000 | 62-68% |
At Sonnet 4.6 rates, the two-provider implementation costs $0.30-$0.57 with skills versus $0.15-$0.10 without – a savings of $0.10-$0.37 per implementation. The skill file investment (15 minutes to create) pays back on the first provider integration.
Find the right skill → Browse 155+ skills in our Skill Finder.
Related Guides
Try it: Paste your error into our Error Diagnostic for an instant fix.
- Structured Error Handling to Reduce Claude Code Token Waste – prevent debugging loops
- Claude Code Caching Strategies: Don’t Re-Discover What You Already Know – pre-stage configuration as a caching strategy
- Claude Code Skills Guide – creating effective skill files