Quick Start
Get IDPFlare up and running in less than 5 minutes.
Prerequisites
- Node.js 18 or later
- A Cloudflare account (free tier works fine)
- Wrangler CLI installed (
npm install -g wrangler)
Quick Installation
# Fork the repository (best results) or clone
git clone https://github.com/IdpFlare/idpflare
cd idpflare
# Install dependencies
npm install
# Login to Cloudflare
wrangler login
# Create D1 database
wrangler d1 create idpflare-db
# Create KV namespaces
wrangler kv namespace create SESSIONS
wrangler kv namespace create RATE_LIMIT
# Generate JWT keys
npm run generate:keys
# Run migrations
npm run db:migrate
# Deploy
npm run deploy
wrangler.toml and
add secrets to .dev.vars for local development.
Installation
Detailed installation guide for setting up IDPFlare.
Step 1: Clone the Repository
git clone https://github.com/yourusername/idpflare
cd idpflare
npm install
Step 2: Create Cloudflare Resources
First, authenticate with Cloudflare:
wrangler login
Create the D1 database:
wrangler d1 create idpflare-db
# Copy the database_id from the output and update wrangler.toml:
# [[d1_databases]]
# binding = "DB"
# database_name = "idpflare-db"
# database_id = "your-database-id"
Create KV namespaces:
wrangler kv namespace create SESSIONS
wrangler kv namespace create RATE_LIMIT
# Update wrangler.toml with the namespace IDs
Step 3: Generate JWT Keys
# Generate RS256 key pair
npm run generate:keys
# This creates a key pair and outputs the values
# Add them as secrets:
wrangler secret put JWT_PRIVATE_KEY
wrangler secret put JWT_PUBLIC_KEY
wrangler secret put ENCRYPTION_KEY
Step 4: Run Migrations
# For local development
npm run db:migrate:local
# For production
npm run db:migrate
Step 5: Deploy
npm run deploy
Configuration
IDPFlare is configured via wrangler.toml and secrets. Everything is customizable without
touching code.
Branding
[vars]
BRAND_NAME = "MyApp"
BRAND_TAGLINE = "Secure authentication for everyone"
BRAND_LOGO_URL = "https://example.com/logo.png"
BRAND_FAVICON_URL = "https://example.com/favicon.ico"
Colors & Theme
THEME_PRIMARY_COLOR = "#6366f1"
THEME_SECONDARY_COLOR = "#4f46e5"
THEME_ACCENT_COLOR = "#f59e0b"
THEME_BACKGROUND_COLOR = "#0f172a"
THEME_SURFACE_COLOR = "#1e293b"
Security Settings
PASSWORD_MIN_LENGTH = "12"
REQUIRE_EMAIL_VERIFICATION = "true"
ALLOW_REGISTRATION = "true"
RATE_LIMIT_LOGIN_ATTEMPTS = "5"
RATE_LIMIT_WINDOW_SECONDS = "900"
Session & Token Settings
SESSION_DURATION_SECONDS = "2592000" # 30 days
ACCESS_TOKEN_DURATION_SECONDS = "3600" # 1 hour
REFRESH_TOKEN_DURATION_SECONDS = "2592000"
ID_TOKEN_DURATION_SECONDS = "3600"
MFA Settings
MFA_MODE = "optional" # optional, required, or disabled
MFA_TOTP_ENABLED = "true"
MFA_EMAIL_ENABLED = "true"
MFA_SECURITY_QUESTIONS_ENABLED = "true"
OAuth 2.0 / OpenID Connect
IDPFlare implements OAuth 2.0 and OpenID Connect protocols with full support for modern flows.
Supported Grant Types
- Authorization Code (with PKCE) — Recommended for web and mobile apps
- Refresh Token — For obtaining new access tokens
- Client Credentials — For machine-to-machine authentication
Supported Scopes
| Scope | Description |
|---|---|
openid |
Required for OIDC. Returns sub claim. |
profile |
Returns name, given_name, family_name, picture, locale |
email |
Returns email and email_verified claims |
offline_access |
Returns a refresh token |
Discovery Endpoint
GET https://your-domain.com/.well-known/openid-configuration
JWKS Endpoint
GET https://your-domain.com/.well-known/jwks.json
Authorization Endpoint
GET https://your-domain.com/oauth/authorize
?client_id=your-client-id
&redirect_uri=https://yourapp.com/callback
&response_type=code
&scope=openid profile email
&code_challenge=...
&code_challenge_method=S256
&state=random-state
Token Endpoint
POST https://your-domain.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=...
&client_id=your-client-id
&redirect_uri=https://yourapp.com/callback
&code_verifier=...
Example Integration
// Using oidc-client-ts
import { UserManager } from 'oidc-client-ts';
const userManager = new UserManager({
authority: 'https://your-domain.com',
client_id: 'your-client-id',
redirect_uri: 'https://yourapp.com/callback',
response_type: 'code',
scope: 'openid profile email',
});
// Start login
await userManager.signinRedirect();
SAML 2.0
IDPFlare supports SAML 2.0 as an Identity Provider (IdP) for enterprise SSO integrations.
SAML Endpoints
| Endpoint | URL |
|---|---|
| Metadata | /saml/metadata |
| SSO (Redirect) | /saml/sso |
| SSO (POST) | /saml/sso |
| Single Logout | /saml/slo |
Configuring a Service Provider
Add your Service Provider to the database:
INSERT INTO saml_service_providers (
id, entity_id, name, acs_url,
name_id_format, sign_assertions, sign_response,
created_at, updated_at
) VALUES (
'sp-id',
'https://app.example.com/saml/metadata',
'My Application',
'https://app.example.com/saml/acs',
'email',
1, 1,
1706745600000, 1706745600000
);
Supported Name ID Formats
email— User's email addresspersistent— Persistent user identifiertransient— Temporary session identifier
Attribute Mapping
Default attributes sent in SAML assertions:
| Attribute | Value |
|---|---|
email |
User's email |
firstName |
User's given name |
lastName |
User's family name |
displayName |
Full name |
Multi-Factor Authentication
IDPFlare supports multiple MFA methods for enhanced security.
Supported Methods
- TOTP — Time-based One-Time Password (Google Authenticator, Authy, etc.)
- Email — Email verification codes
- Security Questions — Knowledge-based verification
- Backup Codes — Emergency recovery codes
Configuration
[vars]
MFA_MODE = "optional" # optional, required, or disabled
# Enable/disable specific methods
MFA_TOTP_ENABLED = "true"
MFA_EMAIL_ENABLED = "true"
MFA_SECURITY_QUESTIONS_ENABLED = "true"
# Security questions settings
MFA_SECURITY_QUESTIONS_MIN_REQUIRED = "3"
MFA_SECURITY_QUESTIONS_VERIFY_COUNT = "2"
MFA Modes
| Mode | Description |
|---|---|
disabled |
MFA is not available |
optional |
Users can choose to enable MFA |
required |
All users must set up MFA |
TOTP Setup Flow
- User navigates to account settings
- System generates TOTP secret and QR code
- User scans QR code with authenticator app
- User verifies by entering a code
- Backup codes are generated for recovery
Admin MFA Management
Admins can reset user MFA via the Management API:
# View user's MFA enrollments
GET /api/v1/users/{userId}/mfa
# Reset all MFA methods
DELETE /api/v1/users/{userId}/mfa
# Reset specific method
DELETE /api/v1/users/{userId}/mfa?method=totp
Admin Dashboard
IDPFlare includes a full-featured admin dashboard for managing users, clients, API keys, and viewing system settings.
Setting Up Admin Access
First, set a user as admin in the database:
# Set user as admin
wrangler d1 execute idpflare-db --local --command \
"UPDATE users SET roles = 'admin' WHERE email = '[email protected]'"
# For production:
wrangler d1 execute idpflare-db --remote --command \
"UPDATE users SET roles = 'admin' WHERE email = '[email protected]'"
Accessing the Admin Panel
Navigate to /admin on your deployed instance. You'll need to log in with an admin user.
Features
- Dashboard: View user statistics and system health
- User Management: Create, edit, delete, block/unblock users
- OAuth Clients: Manage applications and rotate secrets
- API Keys: Generate and manage API keys with scoped permissions
- Audit Logs: View security events and user activity
- Settings: View current system configuration
Management API
Programmatically manage users, applications, and configuration via RESTful APIs with full OpenAPI documentation.
Base URL
https://your-domain.com/api/v1
API Specification
IDPFlare provides full OpenAPI 3.1 specification for the Management API with interactive Swagger UI documentation.
Swagger UI (Interactive Documentation)
Access the interactive API documentation at:
https://your-domain.com/api/v1/docs
The Swagger UI allows you to:
- Browse all available endpoints
- View request/response schemas
- Test API calls directly from your browser
- Authenticate with your API key or admin token
OpenAPI Specification (YAML)
Download the raw OpenAPI specification at:
https://your-domain.com/api/v1/openapi.yaml
Use this specification to:
- Generate client SDKs in your preferred language
- Import into API testing tools (Postman, Insomnia, etc.)
- Integrate with API gateways and documentation platforms
- Validate API requests and responses
Available Endpoints
| Resource | Operations |
|---|---|
| Users | List, Create, Read, Update, Delete, Block/Unblock |
| User Sessions | List, Revoke |
| User MFA | List enrollments, Reset |
| User Identities | List, Unlink social connections |
| OAuth Clients | List, Create, Read, Update, Delete, Rotate Secret |
| API Keys | List, Create, Revoke |
| Audit Logs | Query, Filter |
| Statistics | User stats |
API Authentication
The Management API supports two authentication methods:
1. API Key (Recommended for Backends)
Create an API key through the admin dashboard, then use it in requests:
curl https://your-domain.com/api/v1/users \
-H "Authorization: Bearer idk_your_api_key_here"
2. Admin Token (JWT)
Use a JWT access token from a user with admin role:
curl https://your-domain.com/api/v1/users \
-H "Authorization: Bearer your_jwt_token"
Available Scopes
API keys can be created with granular permissions:
| Scope | Description |
|---|---|
users:read |
Read user information |
users:write |
Create and update users |
users:delete |
Delete users |
clients:read |
Read OAuth client information |
clients:write |
Create and update OAuth clients |
clients:delete |
Delete OAuth clients |
api-keys:read |
Read API keys |
api-keys:write |
Create API keys |
api-keys:delete |
Revoke API keys |
audit:read |
Read audit logs |
stats:read |
Read statistics |
* |
Full access |
User Management API
List Users
GET /api/v1/users?limit=50&offset=0&search=john&role=admin&is_active=true
Get User
GET /api/v1/users/{userId}
Create User
POST /api/v1/users
Content-Type: application/json
{
"email": "[email protected]",
"password": "SecurePassword123!",
"given_name": "John",
"family_name": "Doe",
"roles": ["user"],
"email_verified": true,
"is_active": true,
"metadata": {
"department": "Engineering"
}
}
Update User
PATCH /api/v1/users/{userId}
Content-Type: application/json
{
"roles": ["user", "admin"],
"is_active": true,
"metadata": {
"department": "Management"
}
}
Delete User
DELETE /api/v1/users/{userId}
Update Password
PUT /api/v1/users/{userId}/password
Content-Type: application/json
{
"password": "NewSecurePassword123!"
}
Block User
Blocks a user and revokes all active sessions and tokens:
POST /api/v1/users/{userId}/block
Content-Type: application/json
{
"reason": "Suspicious activity detected"
}
Unblock User
POST /api/v1/users/{userId}/unblock
List User Sessions
GET /api/v1/users/{userId}/sessions
Revoke All Sessions
DELETE /api/v1/users/{userId}/sessions
List User MFA Enrollments
GET /api/v1/users/{userId}/mfa
Reset User MFA
# Reset all MFA
DELETE /api/v1/users/{userId}/mfa
# Reset specific method
DELETE /api/v1/users/{userId}/mfa?method=totp
List Social Identities
GET /api/v1/users/{userId}/identities
Unlink Social Identity
DELETE /api/v1/users/{userId}/identities/{identityId}
OAuth Clients API
Manage OAuth 2.0 applications (clients) that can authenticate with your identity provider.
List Clients
GET /api/v1/clients?limit=50&offset=0&is_active=true
Get Client
GET /api/v1/clients/{clientId}
Create Client
POST /api/v1/clients
Content-Type: application/json
{
"name": "My Application",
"description": "Main web application",
"redirect_uris": [
"https://myapp.com/callback",
"https://myapp.com/silent-callback"
],
"allowed_origins": ["https://myapp.com"],
"is_confidential": true,
"is_first_party": false,
"allowed_grant_types": ["authorization_code", "refresh_token"],
"allowed_scopes": ["openid", "profile", "email", "offline_access"],
"require_pkce": true,
"access_token_ttl": 3600,
"refresh_token_ttl": 2592000
}
client_secret which is only shown once.
Store it securely!
Update Client
PATCH /api/v1/clients/{clientId}
Content-Type: application/json
{
"name": "My Application (Updated)",
"redirect_uris": [
"https://myapp.com/callback",
"https://staging.myapp.com/callback"
],
"is_active": true
}
Delete Client
DELETE /api/v1/clients/{clientId}
Rotate Client Secret
Generate a new client secret (confidential clients only):
POST /api/v1/clients/{clientId}/rotate-secret
Response:
{
"client_secret": "new_secret_value_store_this_securely"
}
Client Types
| Type | is_confidential | Use Case |
|---|---|---|
| Confidential | true |
Server-side apps that can securely store secrets |
| Public | false |
SPAs, mobile apps (use PKCE) |
API Keys Management
API keys provide programmatic access to the Management API.
List API Keys
GET /api/v1/api-keys?limit=50&active_only=true
Create API Key
POST /api/v1/api-keys
Content-Type: application/json
{
"name": "Backend Service Key",
"scopes": ["users:read", "users:write", "audit:read"],
"metadata": {
"service": "user-sync",
"environment": "production"
}
}
Response:
{
"api_key": {
"id": "key_abc123",
"name": "Backend Service Key",
"key_prefix": "idk_abc123...",
"scopes": ["users:read", "users:write", "audit:read"],
"is_active": true,
"created_at": 1706745600000
},
"raw_key": "idk_abc123def456ghi789..."
}
raw_key is only shown once. Store it securely in your
secrets manager!
Revoke API Key
DELETE /api/v1/api-keys/{keyId}
Audit Logs API
Query security and activity audit logs for compliance and monitoring.
Query Audit Logs
GET /api/v1/audit-logs?limit=50&offset=0
&user_id=user_123
&event_type=login_success
&status=success
&start_date=1706745600000
&end_date=1706832000000
Get User Audit Logs
GET /api/v1/audit-logs/user/{userId}?limit=50
Get User Security Events
Returns recent security-relevant events (failed logins, MFA changes, etc.):
GET /api/v1/audit-logs/user/{userId}/security?limit=10
Event Types
| Event Type | Description |
|---|---|
login_success |
Successful login |
login_failure |
Failed login attempt |
logout |
User logged out |
register_success |
New user registration |
password_reset_request |
Password reset requested |
password_reset_success |
Password was reset |
mfa_setup_totp |
TOTP MFA enabled |
mfa_verify_failure |
Failed MFA verification |
oauth_token_issued |
OAuth token generated |
account_locked |
Account was locked |
admin_user_created |
Admin created a user |
admin_user_deleted |
Admin deleted a user |
Hooks & Extensibility
Customize IDPFlare's behavior by deploying external Cloudflare Workers that hook into key lifecycle
events. You can deploy these as completely separate services, or manage them within the
hooks/ directory of your IDPFlare project (note: managing them in-repo may require
resolving merge conflicts when updating IDPFlare).
How it Works
When specific events occur (like user registration or token generation), IDPFlare makes an HTTP POST request to your configured worker URL. Your worker processes the request and returns a JSON response instructing IDPFlare on how to proceed.
Available Hooks
| Hook Name | Variable | Trigger |
|---|---|---|
pre-register |
HOOK_PRE_REGISTER |
Before a new user is created. Use to validate email, check blocklists, or require specific fields. |
post-register |
HOOK_POST_REGISTER |
After a user is successfully created. Use to send welcome emails or sync with CRM. |
pre-login |
HOOK_PRE_LOGIN |
Before credentials are verified. Use to block suspicious IPs or enforce maintenance windows. |
post-login |
HOOK_POST_LOGIN |
After successful login. Use for audit logging or updating last-login timestamps. |
token-claims |
HOOK_TOKEN_CLAIMS |
During token generation. Use to add custom claims (roles, permissions) to the JWT. |
scope-handler |
HOOK_SCOPE_HANDLER |
During scope validation. Use to implement dynamic scope rules. |
How to Implement
Hooks serve as separate Cloudflare Workers. Here is an example of a Token Claims hook:
// worker.ts
export default {
async fetch(request, env) {
if (request.method !== 'POST') {
return new Response('Method not allowed', { status: 405 });
}
// 1. Parse the payload
const payload = await request.json();
const { user, scope, client_id } = payload;
// 2. Define custom claims
const claims = {};
// Example: Add roles from user metadata
if (user.metadata?.roles) {
claims.roles = user.metadata.roles;
}
// Example: Add a 'premium' claim for specific email domains
if (user.email.endsWith('@example.com')) {
claims.is_premium = true;
}
// 3. Return claims as JSON
return Response.json(claims);
}
};
How to Wire Up
Once your hook worker is deployed, configure IDPFlare to use it by setting the corresponding
environment variable in wrangler.toml:
[vars]
# ... other config ...
# Extensibility Hooks
HOOK_TOKEN_CLAIMS = "https://token-claims.your-hooks.workers.dev"
HOOK_PRE_REGISTER = "https://pre-register.your-hooks.workers.dev"
Monolithic Deployment (Internal Hooks)
If you prefer not to manage separate Worker services, you can host your hooks directly within the IDPFlare application as internal routes (note: managing them in-repo may require resolving merge conflicts when updating IDPFlare).
- Create a hooks route file:
Create
src/routes/hooks.tsand implement your logic:import { Hono } from 'hono'; const hooks = new Hono(); hooks.post('/token-claims', async (c) => { const payload = await c.req.json(); // Your custom logic here return c.json({ roles: ['custom-role'] }); }); export default hooks; - Register the route in
src/index.ts:import hooksRoutes from './routes/hooks'; // ... app.route('/hooks', hooksRoutes); - Configure IDPFlare to call itself:
Update
wrangler.tomlto point to your application's own URL:[vars] HOOK_TOKEN_CLAIMS = "https://auth.yourdomain.com/hooks/token-claims"
Client SDK
IDPFlare provides an official TypeScript/JavaScript SDK for easy integration.
Installation
npm install idpflare-client
Basic Usage
import { IDPFlareClient } from 'idpflare-client';
const client = new IDPFlareClient({
authority: 'https://auth.yourdomain.com',
clientId: 'your-client-id',
redirectUri: 'https://yourapp.com/callback',
scopes: ['openid', 'profile', 'email'],
});
// Start login
await client.login();
// Handle callback (on callback page)
await client.handleCallback();
// Check if authenticated
if (client.isAuthenticated()) {
const user = client.getUser();
console.log('Logged in as:', user.email);
}
// Make authenticated API calls
const response = await client.fetch('/api/data');
// Logout
await client.logout();
React Integration
The SDK includes React-specific hooks and components.
Setup Provider
import { IDPFlareProvider } from 'idpflare-client/react';
function App() {
return (
<IDPFlareProvider
authority="https://auth.yourdomain.com"
clientId="your-client-id"
redirectUri="https://yourapp.com/callback"
scopes={['openid', 'profile', 'email']}
>
<YourApp />
</IDPFlareProvider>
);
}
Using Hooks
import { useAuth, useUser } from 'idpflare-client/react';
function ProfilePage() {
const { isAuthenticated, isLoading, login, logout } = useAuth();
const user = useUser();
if (isLoading) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
return <button onClick={login}>Log In</button>;
}
return (
<div>
<h1>Welcome, {user?.name}!</h1>
<p>Email: {user?.email}</p>
<button onClick={logout}>Log Out</button>
</div>
);
}
Protected Routes
import { useAuth } from 'idpflare-client/react';
import { Navigate } from 'react-router-dom';
function ProtectedRoute({ children }) {
const { isAuthenticated, isLoading, login } = useAuth();
if (isLoading) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
// Redirect to login
login();
return null;
}
return children;
}
Deployment
Deploying to Cloudflare Workers
# Deploy to production
npm run deploy
# Deploy with specific environment
wrangler deploy --env production
Production Checklist
- ✅ Set all required secrets (JWT keys, encryption key)
- ✅ Configure email provider for verification emails
- ✅ Set up custom domain with HTTPS
- ✅ Update BASE_URL in wrangler.toml
- ✅ Create initial admin user
- ✅ Configure rate limiting appropriately
- ✅ Enable audit logging
Custom Domain
Add a custom domain through the Cloudflare dashboard:
- Go to Workers & Pages
- Select your IDPFlare worker
- Go to Settings → Triggers
- Click "Add Custom Domain"
- Enter your domain (e.g., auth.yourdomain.com)
- Update BASE_URL in wrangler.toml
[vars]
BASE_URL = "https://auth.yourdomain.com"
auth.yourdomain.com for better organization
and cookie security.
Environment Variables
Complete reference of all configuration options.
Required Secrets
Set these using wrangler secret put:
| Secret | Description |
|---|---|
JWT_PRIVATE_KEY |
RSA private key for signing JWTs |
JWT_PUBLIC_KEY |
RSA public key for verifying JWTs |
ENCRYPTION_KEY |
AES key for encrypting sensitive data |
Email Provider (Choose One)
| Secret | Description |
|---|---|
RESEND_API_KEY |
Resend API key |
SENDGRID_API_KEY |
SendGrid API key |
MAILGUN_API_KEY |
Mailgun API key |
Social Providers (Optional)
| Secret | Description |
|---|---|
GOOGLE_CLIENT_ID |
Google OAuth client ID |
GOOGLE_CLIENT_SECRET |
Google OAuth client secret |
GITHUB_CLIENT_ID |
GitHub OAuth client ID |
GITHUB_CLIENT_SECRET |
GitHub OAuth client secret |
MICROSOFT_CLIENT_ID |
Microsoft OAuth client ID |
MICROSOFT_CLIENT_SECRET |
Microsoft OAuth client secret |
Configuration Variables
Set these in wrangler.toml under [vars]:
[vars]
# Base URL (required for production)
BASE_URL = "https://auth.yourdomain.com"
# Branding
BRAND_NAME = "MyApp"
BRAND_TAGLINE = "Secure authentication"
BRAND_LOGO_URL = "https://example.com/logo.png"
# Theme Colors
THEME_PRIMARY_COLOR = "#6366f1"
THEME_BACKGROUND_COLOR = "#0f172a"
# Security
PASSWORD_MIN_LENGTH = "12"
REQUIRE_EMAIL_VERIFICATION = "true"
ALLOW_REGISTRATION = "true"
# Rate Limiting
RATE_LIMIT_LOGIN_ATTEMPTS = "5"
RATE_LIMIT_WINDOW_SECONDS = "900"
# Session/Token Durations
SESSION_DURATION_SECONDS = "2592000"
ACCESS_TOKEN_DURATION_SECONDS = "3600"
REFRESH_TOKEN_DURATION_SECONDS = "2592000"
# MFA
MFA_MODE = "optional"
MFA_TOTP_ENABLED = "true"
MFA_EMAIL_ENABLED = "true"
# Social Login
SOCIAL_GOOGLE_ENABLED = "true"
SOCIAL_GITHUB_ENABLED = "true"
SOCIAL_MICROSOFT_ENABLED = "false"
# Email
EMAIL_PROVIDER = "resend"
EMAIL_FROM_ADDRESS = "[email protected]"
EMAIL_FROM_NAME = "MyApp Auth"
Social Login
IDPFlare supports authentication via popular social providers.
Supported Providers
Setting Up Google
https://your-domain.com/auth/callback/googleSetting Up GitHub
https://your-domain.com/auth/callback/githubSetting Up Microsoft
https://your-domain.com/auth/callback/microsoftEnabling Providers
Enable providers in
wrangler.toml: