@harperfast/oauth
v2.0.0
Published
OAuth 2.0 authentication plugin for Harper
Readme
Harper OAuth Plugin
OAuth 2.0 and OpenID Connect authentication for Harper applications. Supports GitHub, Google, Azure AD, Auth0, and custom OIDC providers with automatic token refresh and lifecycle hooks for user provisioning.
Features
- Multi-provider support - GitHub, Google, Azure AD, Auth0, and custom OIDC providers
- Automatic token refresh - Proactive token renewal on every request
- Lifecycle hooks - Extensible hooks for user provisioning and custom logic
- CSRF protection - Distributed token storage for cluster support
- ID token verification - Full OIDC support with signature validation
- Zero configuration - Works with Harper's session system automatically
Installation
Requires Harper v5 (harper >=5.0.0). For Harper v4 (the legacy harperdb package), use the 1.x line.
npm install @harperfast/oauthQuick Start
1. Configure OAuth Plugin
Add to your config.yaml:
'@harperfast/oauth':
package: '@harperfast/oauth'
providers:
github:
clientId: ${OAUTH_GITHUB_CLIENT_ID}
clientSecret: ${OAUTH_GITHUB_CLIENT_SECRET}2. Set Environment Variables
export OAUTH_GITHUB_CLIENT_ID="your-client-id"
export OAUTH_GITHUB_CLIENT_SECRET="your-client-secret"Note: The
exportcommands above are for local development and quick testing only. You can also use a.envfile withdotenv-clifor local dev — just don't commit it. For Harper Fabric deployments, see the Harper Fabric documentation for managing runtime environment variables.
3. Configure OAuth Callback
Set your OAuth callback URL in your provider settings:
https://your-domain/oauth/github/callback4. (Optional) Register Lifecycle Hooks
Create or update users when they log in:
// resources.ts
import { registerHooks } from '@harperfast/oauth';
registerHooks({
onLogin: async (oauthUser, tokenResponse, session, request, provider) => {
const { User } = tables;
// Find or create user
let user;
for await (const existing of User.search({ email: oauthUser.email })) {
user = existing;
break;
}
if (!user) {
user = await User.create({
email: oauthUser.email,
name: oauthUser.name,
provider: provider,
});
}
return { user: String(user.id) };
},
});
// Export your resources...5. Test Authentication
Navigate to:
http://localhost:9926/oauth/github/loginUsage
Access authenticated user in your resources:
export class MyResource extends tables.Resource {
async get(target, request) {
if (!request.session?.user) {
throw new ClientError('Not authenticated', 401);
}
return {
userId: request.session.user,
email: request.session.oauthUser.email,
};
}
}Supported Providers
Built-in provider templates (not active until configured):
- GitHub - OAuth 2.0
- Google - OpenID Connect
- Azure AD - OpenID Connect
- Auth0 - OpenID Connect
- Okta - OpenID Connect (with multi-tenant support)
- Custom OIDC - Any compliant provider
Note: Built-in providers are templates that require configuration. None are active until you provide OAuth credentials (
clientId,clientSecret, etc.). Having provider code in the plugin does not enable authentication or create security exposure.
How It Works
The plugin automatically handles:
- OAuth Flow - Redirects to provider, handles callback, exchanges code for tokens
- Token Management - Validates and refreshes tokens on every HTTP request
- Session Integration - Stores OAuth data in Harper sessions
- CSRF Protection - Validates state parameter using distributed token storage
- Auto-logout - Clears session when tokens expire and can't be refreshed
Documentation
Complete documentation is available in the docs directory:
- Getting Started - Installation and quick start guide
- Configuration - Complete configuration reference
- OAuth Providers - Provider setup guides
- Lifecycle Hooks - User provisioning and custom logic
- Multi-Tenant SSO - Per-organization OAuth providers for B2B SaaS
- Token Refresh and Sessions - How OAuth tokens and Harper sessions interact
- API Reference - Endpoints and programmatic API
Development
Build
npm install
npm run buildTest
npm test
npm run test:coverageLint & Format
npm run lint
npm run format:check
npm run format:writeDatabase Schema
The plugin creates a csrf_tokens table for CSRF protection:
type CSRFToken @table {
token: string @key
sessionId: string
provider: string
originalUrl: string
createdAt: number
expiresAt: number @index
}Tokens automatically expire after 10 minutes.
When MCP OAuth is enabled (see issue #86), the plugin also creates a harper_oauth_mcp_clients table for RFC 7591 Dynamic Client Registration. Registrations persist indefinitely so client_ids cached by MCP clients (Claude Desktop, Cursor, mcp-remote) survive Harper restarts.
MCP OAuth (experimental)
The plugin can also act as an OAuth authorization server for Model Context Protocol clients (Claude Desktop, Cursor, mcp-remote), letting them authenticate against the same upstream providers. Enable it with mcp.enabled: true (see docs/configuration.md).
Status: experimental, opt-in. Available now: RFC 7591 Dynamic Client Registration, discovery metadata (/.well-known/*), the authorization endpoint, and audience-bound JWT token issuance. Token verification for app-owned MCP routes (withMCPAuth) and the remaining pieces land in 2.0.x — see issue #86.
Security Considerations
- HTTPS required - OAuth requires HTTPS in production
- CSRF protection - Automatic via state parameter validation
- ID token verification - OIDC providers verify token signatures
- Secure sessions - Use Harper's secure session configuration
- Token storage - Tokens stored in session (configure secure cookies)
- MCP client registration (when
mcp.enabledis true) - The/oauth/mcp/registerendpoint defaults to open registration per RFC 7591. Setmcp.dynamicClientRegistration.initialAccessTokento require a bearer token on registration, ormcp.dynamicClientRegistration.allowedRedirectUriHoststo restrict which hosts may registerredirect_uris. Seedocs/configuration.md.
Debug Mode
Enable debug endpoints for testing:
'@harperfast/oauth':
debug: true
providers:
github:
clientId: ${OAUTH_GITHUB_CLIENT_ID}
clientSecret: ${OAUTH_GITHUB_CLIENT_SECRET}Debug endpoints:
GET /oauth/- List configured providersGET /oauth/test- Interactive test pageGET /oauth/{provider}/user- View current sessionGET /oauth/{provider}/refresh- Trigger token refresh
Warning: Never enable debug mode in production.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Copyright 2025 HarperDB, Inc.
