Back to Skills

oauth-integrations

verified

Implement OAuth 2.0 authentication with GitHub and Microsoft Entra (Azure AD) in Cloudflare Workers and other edge environments. Covers provider-specific quirks, required headers, scope requirements, and token handling without MSAL. Use when: implementing GitHub OAuth, Microsoft/Azure AD authentication, handling OAuth callbacks, or troubleshooting 403 errors in OAuth flows.

View on GitHub

Marketplace

claude-skills

jezweb/claude-skills

Plugin

frontend

Repository

jezweb/claude-skills
211stars

skills/oauth-integrations/SKILL.md

Last Verified

January 21, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/jezweb/claude-skills/blob/main/skills/oauth-integrations/SKILL.md -a claude-code --skill oauth-integrations

Installation paths:

Claude
.claude/skills/oauth-integrations/
Powered by add-skill CLI

Instructions

# OAuth Integrations for Edge Environments

Implement GitHub and Microsoft OAuth in Cloudflare Workers and other edge runtimes.

## GitHub OAuth

### Required Headers

GitHub API has strict requirements that differ from other providers.

| Header | Requirement |
|--------|-------------|
| `User-Agent` | **REQUIRED** - Returns 403 without it |
| `Accept` | `application/vnd.github+json` recommended |

```typescript
const resp = await fetch('https://api.github.com/user', {
  headers: {
    Authorization: `Bearer ${accessToken}`,
    'User-Agent': 'MyApp/1.0',  // Required!
    'Accept': 'application/vnd.github+json',
  },
});
```

### Private Email Handling

GitHub users can set email to private (`/user` returns `email: null`).

```typescript
if (!userData.email) {
  const emails = await fetch('https://api.github.com/user/emails', { headers })
    .then(r => r.json());
  userData.email = emails.find(e => e.primary && e.verified)?.email;
}
```

Requires `user:email` scope.

### Token Exchange

Token exchange returns form-encoded by default. Add Accept header for JSON:

```typescript
const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Accept': 'application/json',  // Get JSON response
  },
  body: new URLSearchParams({ code, client_id, client_secret, redirect_uri }),
});
```

### GitHub OAuth Notes

| Issue | Solution |
|-------|----------|
| Callback URL | Must be EXACT - no wildcards, no subdirectory matching |
| Token exchange returns form-encoded | Add `'Accept': 'application/json'` header |
| Tokens don't expire | No refresh flow needed, but revoked = full re-auth |

## Microsoft Entra (Azure AD) OAuth

### Why MSAL Doesn't Work in Workers

MSAL.js depends on:
- Browser APIs (localStorage, sessionStorage, DOM)
- Node.js crypto module

Cloudflare's V8 isolate runtime has neither. Use manual OAuth instead:
1. Manual OAuth URL construction
2. Dire

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
4817 chars