Skip to content

Commit 7642cc0

Browse files
committed
feat: add Auth0 emulator
1 parent 6f1175c commit 7642cc0

32 files changed

Lines changed: 2778 additions & 11 deletions

README.md

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ afterAll(() => Promise.all([github.close(), vercel.close()]))
141141

142142
| Option | Default | Description |
143143
|--------|---------|-------------|
144-
| `service` | *(required)* | Service name: `'vercel'`, `'github'`, `'google'`, `'slack'`, `'apple'`, `'microsoft'`, or `'aws'` |
144+
| `service` | *(required)* | Service name: `'vercel'`, `'github'`, `'google'`, `'slack'`, `'apple'`, `'microsoft'`, `'aws'`, or `'auth0'` |
145145
| `port` | `4000` | Port for the HTTP server |
146146
| `seed` | none | Inline seed data (same shape as YAML config) |
147147
| `baseUrl` | none | Override advertised base URL. Per-service `baseUrl` in seed config takes highest priority, then this option, then `EMULATE_BASE_URL` env var (supports `{service}`), then `PORTLESS_URL` (supports `{service}`, automatically set by the `portless` CLI wrapper), then `http://localhost:<port>`. |
@@ -299,6 +299,24 @@ aws:
299299
roles:
300300
- role_name: lambda-execution-role
301301
description: Role for Lambda function execution
302+
303+
auth0:
304+
tenant: my-tenant
305+
applications:
306+
- client_id: my-app
307+
client_secret: secret
308+
callbacks:
309+
- http://localhost:3000/api/auth/callback
310+
grant_types: [authorization_code, refresh_token, client_credentials]
311+
users:
312+
- email: dev@example.com
313+
name: Developer
314+
password: pass
315+
roles:
316+
- name: admin
317+
connections:
318+
- name: Username-Password-Authentication
319+
strategy: auth0
302320
```
303321
304322
## OAuth & Integrations
@@ -399,6 +417,25 @@ microsoft:
399417
- "http://localhost:3000/api/auth/callback/microsoft-entra-id"
400418
```
401419

420+
### Auth0 Applications
421+
422+
```yaml
423+
auth0:
424+
tenant: "my-tenant"
425+
applications:
426+
- client_id: "my-app"
427+
client_secret: "secret"
428+
callbacks:
429+
- "http://localhost:3000/api/auth/callback"
430+
grant_types:
431+
- authorization_code
432+
- refresh_token
433+
- client_credentials
434+
apis:
435+
- audience: "https://api.example.test/"
436+
name: "Example API"
437+
```
438+
402439
## Vercel API
403440

404441
Every endpoint below is fully stateful with Vercel-style JSON responses and cursor-based pagination.
@@ -690,6 +727,22 @@ All operations via `POST /iam/` with `Action` parameter:
690727
All operations via `POST /sts/` with `Action` parameter:
691728
- `GetCallerIdentity`, `AssumeRole`
692729

730+
## Auth0 API
731+
732+
Auth0 identity provider emulation with tenant-aware OIDC discovery, Universal Login pages, PKCE, refresh token rotation, Userinfo, and Management API resources.
733+
734+
- `GET /.well-known/openid-configuration` - OIDC discovery document
735+
- `GET /.well-known/jwks.json` - JSON Web Key Set (JWKS)
736+
- `GET /authorize` - authorization endpoint (shows Universal Login)
737+
- `POST /oauth/token` - token exchange (authorization code, refresh token, client credentials)
738+
- `GET /userinfo` - OpenID Connect user info
739+
- `GET /v2/logout` - logout
740+
- `GET /api/v2/users` / `POST /api/v2/users` - list and create users
741+
- `GET /api/v2/roles` / `POST /api/v2/roles` - list and create roles
742+
- `GET /api/v2/applications` / `POST /api/v2/applications` - list and create applications
743+
- `GET /api/v2/organizations` / `POST /api/v2/organizations` - list and create organizations
744+
- `GET /api/v2/connections` / `POST /api/v2/connections` - list and create connections
745+
693746
## Next.js Integration
694747

695748
Embed emulators directly in your Next.js app so they run on the same origin. This solves the Vercel preview deployment problem where OAuth callback URLs change with every deployment.

apps/web/app/docs/architecture/page.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ packages/
1717
mongoatlas/ # MongoDB Atlas Admin API + Data API
1818
resend/ # Resend email API
1919
stripe/ # Stripe billing and payments API
20+
auth0/ # Auth0 identity provider / OIDC
2021
apps/
2122
web/ # Documentation site (Next.js)
2223
```

apps/web/app/docs/auth0/layout.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { pageMetadata } from "@/lib/page-metadata";
2+
3+
export const metadata = pageMetadata("auth0");
4+
5+
export default function Layout({ children }: { children: React.ReactNode }) {
6+
return children;
7+
}

apps/web/app/docs/auth0/page.mdx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Auth0
2+
3+
Auth0 identity provider emulation with OAuth 2.0 / OIDC, Universal Login pages, refresh token rotation, Userinfo, and Management API resources for users, roles, applications, organizations, and connections.
4+
5+
## OAuth / OIDC
6+
7+
- `GET /.well-known/openid-configuration` — OIDC discovery
8+
- `GET /.well-known/jwks.json` — JSON Web Key Set
9+
- `GET /authorize` — authorization endpoint
10+
- `GET /u/login` — Universal Login page
11+
- `POST /oauth/token` — token endpoint
12+
- `GET /userinfo` — user info
13+
- `GET /v2/logout` — logout
14+
15+
Authorization Code with PKCE is supported with both `plain` and `S256` code challenge methods. The token endpoint supports `authorization_code`, `refresh_token`, and `client_credentials`.
16+
17+
## Tenant URLs
18+
19+
Auth0 advertises tenant-aware URLs. With this config:
20+
21+
```yaml
22+
auth0:
23+
tenant: my-tenant
24+
```
25+
26+
Discovery returns endpoints under:
27+
28+
```text
29+
http://my-tenant.auth0.localhost:4012
30+
```
31+
32+
For test environments that cannot route subdomains, call discovery with a tenant query parameter:
33+
34+
```bash
35+
curl "http://localhost:4012/.well-known/openid-configuration?tenant=my-tenant"
36+
```
37+
38+
The returned endpoints include the same `tenant` parameter.
39+
40+
## Management API
41+
42+
- `GET /api/v2/users` — list users
43+
- `POST /api/v2/users` — create user
44+
- `GET /api/v2/users/:id` — get user
45+
- `PATCH /api/v2/users/:id` — update user
46+
- `DELETE /api/v2/users/:id` — delete user
47+
- `GET /api/v2/users/:id/roles` — list user roles
48+
- `POST /api/v2/users/:id/roles` — assign roles
49+
- `GET /api/v2/roles` — list roles
50+
- `POST /api/v2/roles` — create role
51+
- `GET /api/v2/applications` — list applications
52+
- `POST /api/v2/applications` — create application
53+
- `GET /api/v2/organizations` — list organizations
54+
- `POST /api/v2/organizations` — create organization
55+
- `GET /api/v2/connections` — list connections
56+
- `POST /api/v2/connections` — create connection
57+
58+
## Seed Config
59+
60+
```yaml
61+
auth0:
62+
tenant: my-tenant
63+
applications:
64+
- client_id: my-app
65+
client_secret: secret
66+
name: My App
67+
callbacks:
68+
- http://localhost:3000/api/auth/callback
69+
grant_types:
70+
- authorization_code
71+
- refresh_token
72+
- client_credentials
73+
users:
74+
- email: dev@example.com
75+
name: Developer
76+
password: pass
77+
roles:
78+
- name: admin
79+
connections:
80+
- name: Username-Password-Authentication
81+
strategy: auth0
82+
apis:
83+
- audience: https://api.example.test/
84+
name: Example API
85+
```

apps/web/app/docs/configuration/page.mdx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,34 @@ mongoatlas:
327327
username: app-user
328328
```
329329

330+
## Auth0 Seed Config
331+
332+
```yaml
333+
auth0:
334+
tenant: my-tenant
335+
applications:
336+
- client_id: my-app
337+
client_secret: secret
338+
callbacks:
339+
- http://localhost:3000/api/auth/callback
340+
grant_types:
341+
- authorization_code
342+
- refresh_token
343+
- client_credentials
344+
users:
345+
- email: dev@example.com
346+
name: Developer
347+
password: pass
348+
roles:
349+
- name: admin
350+
connections:
351+
- name: Username-Password-Authentication
352+
strategy: auth0
353+
apis:
354+
- audience: https://api.example.test/
355+
name: Example API
356+
```
357+
330358
## Resend Seed Config
331359

332360
```yaml

apps/web/app/docs/page.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Getting Started
22

3-
Local drop-in replacement for Vercel, GitHub, Google, Slack, Apple, Microsoft, AWS, Okta, MongoDB Atlas, Resend, and Stripe APIs. Built for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation. Not mocks.
3+
Local drop-in replacement for Vercel, GitHub, Google, Slack, Apple, Microsoft, AWS, Okta, MongoDB Atlas, Resend, Stripe, and Auth0 APIs. Built for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation. Not mocks.
44

55
## Quick Start
66

@@ -21,6 +21,7 @@ All services start with sensible defaults. No config file needed:
2121
- **MongoDB Atlas** on `http://localhost:4008`
2222
- **Resend** on `http://localhost:4009`
2323
- **Stripe** on `http://localhost:4010`
24+
- **Auth0** on `http://localhost:4012`
2425

2526
## CLI
2627

apps/web/app/docs/programmatic-api/page.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ afterAll(() => Promise.all([github.close(), vercel.close()]))
5959
<tr>
6060
<td><code>service</code></td>
6161
<td><em>(required)</em></td>
62-
<td>Service name: <code>'vercel'</code>, <code>'github'</code>, <code>'google'</code>, <code>'slack'</code>, <code>'apple'</code>, <code>'microsoft'</code>, <code>'aws'</code>, <code>'okta'</code>, <code>'mongoatlas'</code>, <code>'resend'</code>, or <code>'stripe'</code></td>
62+
<td>Service name: <code>'vercel'</code>, <code>'github'</code>, <code>'google'</code>, <code>'slack'</code>, <code>'apple'</code>, <code>'microsoft'</code>, <code>'aws'</code>, <code>'okta'</code>, <code>'mongoatlas'</code>, <code>'resend'</code>, <code>'stripe'</code>, or <code>'auth0'</code></td>
6363
</tr>
6464
<tr>
6565
<td><code>port</code></td>
@@ -133,6 +133,7 @@ npm install @emulators/github @emulators/google @emulators/stripe
133133
<tr><td><code>@emulators/mongoatlas</code></td><td>MongoDB Atlas Admin API + Data API</td></tr>
134134
<tr><td><code>@emulators/resend</code></td><td>Resend email API</td></tr>
135135
<tr><td><code>@emulators/stripe</code></td><td>Stripe billing and payments API</td></tr>
136+
<tr><td><code>@emulators/auth0</code></td><td>Auth0 identity provider / OIDC</td></tr>
136137
<tr><td><code>@emulators/core</code></td><td>Shared store, middleware, and utilities</td></tr>
137138
<tr><td><code>@emulators/adapter-next</code></td><td>Next.js App Router integration</td></tr>
138139
</tbody>

apps/web/lib/docs-navigation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const allDocsPages: NavItem[] = [
1717
{ name: "AWS", href: "/docs/aws" },
1818
{ name: "Okta", href: "/docs/okta" },
1919
{ name: "MongoDB Atlas", href: "/docs/mongoatlas" },
20+
{ name: "Auth0", href: "/docs/auth0" },
2021
{ name: "Resend", href: "/docs/resend" },
2122
{ name: "Stripe", href: "/docs/stripe" },
2223
{ name: "Authentication", href: "/docs/authentication" },

apps/web/lib/page-titles.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const PAGE_TITLES: Record<string, string> = {
1212
aws: "AWS",
1313
okta: "Okta",
1414
mongoatlas: "MongoDB Atlas",
15+
auth0: "Auth0",
1516
resend: "Resend",
1617
stripe: "Stripe",
1718
authentication: "Authentication",

emulate.config.example.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,27 @@ google:
128128
mime_type: application/vnd.google-apps.folder
129129
parent_ids:
130130
- root
131+
132+
auth0:
133+
tenant: my-tenant
134+
applications:
135+
- client_id: my-app
136+
client_secret: secret
137+
callbacks:
138+
- http://localhost:3000/api/auth/callback
139+
grant_types:
140+
- authorization_code
141+
- refresh_token
142+
- client_credentials
143+
users:
144+
- email: dev@example.com
145+
name: Developer
146+
password: pass
147+
roles:
148+
- name: admin
149+
connections:
150+
- name: Username-Password-Authentication
151+
strategy: auth0
152+
apis:
153+
- audience: https://api.example.test/
154+
name: Example API

0 commit comments

Comments
 (0)