Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ All services start with sensible defaults. No config file needed:
- **Slack** on `http://localhost:4003`
- **Apple** on `http://localhost:4004`
- **Microsoft** on `http://localhost:4005`
- **AWS** on `http://localhost:4006`
- **Okta** on `http://localhost:4006`
- **Auth0** on `http://localhost:4007`
- **AWS** on `http://localhost:4008`
- **Resend** on `http://localhost:4009`
- **Stripe** on `http://localhost:4010`
- **MongoDB Atlas** on `http://localhost:4011`
- **Clerk** on `http://localhost:4012`

## CLI

Expand Down Expand Up @@ -100,7 +106,7 @@ afterAll(() => Promise.all([github.close(), vercel.close()]))

| Option | Default | Description |
|--------|---------|-------------|
| `service` | *(required)* | Service name: `'vercel'`, `'github'`, `'google'`, `'slack'`, `'apple'`, `'microsoft'`, or `'aws'` |
| `service` | *(required)* | Service name: `'vercel'`, `'github'`, `'google'`, `'slack'`, `'apple'`, `'microsoft'`, `'okta'`, `'auth0'`, `'aws'`, `'resend'`, `'stripe'`, `'mongoatlas'`, or `'clerk'` |
| `port` | `4000` | Port for the HTTP server |
| `seed` | none | Inline seed data (same shape as YAML config) |

Expand Down Expand Up @@ -610,6 +616,35 @@ Microsoft Entra ID (Azure AD) v2.0 OAuth 2.0 and OpenID Connect emulation with a
- `GET /oauth2/v2.0/logout` - end session / logout
- `POST /oauth2/v2.0/revoke` - token revocation

## Auth0

Auth0 Authentication API, Management API v2, and OIDC emulation with log event streaming.

### Authentication API
- `POST /oauth/token` — token endpoint (client_credentials, password-realm, refresh_token)
- `GET /userinfo` — user profile from access token
- `POST /oauth/revoke` — revoke refresh token

### Management API v2
- `POST /api/v2/users` — create user with email, password, connection, app_metadata
- `GET /api/v2/users/:id` — get user by ID
- `GET /api/v2/users-by-email` — search users by email
- `PATCH /api/v2/users/:id` — update user (app_metadata merge, password change, email_verified)
- `POST /api/v2/tickets/email-verification` — create email verification ticket

### OIDC
- `GET /.well-known/openid-configuration` — OpenID Connect discovery
- `GET /.well-known/jwks.json` — JSON Web Key Set (RS256)
- `GET /_emulate/public-key.pem` — RSA public key in PEM format

Supports deterministic signing keys via `signing_key` in seed config for static JWT validation. When omitted, a random key pair is generated on first request.

### Log Events
Dispatches Auth0 log events (`ss`, `fs`, `sv`, `scp`) via webhook on user creation, signup failure, email verification, and password change. Configure subscribers via `log_streams` in the seed config.

### Error Fidelity
Authentication API errors use OAuth2 format (`{ error, error_description }`). Management API errors use Auth0 format (`{ statusCode, error, message, errorCode }`). Error strings match Auth0's actual API responses so SDK error handling works unchanged.

## AWS

S3, SQS, IAM, and STS emulation with REST-style S3 paths and query-style SQS/IAM/STS endpoints. All responses use AWS-compatible XML.
Expand Down Expand Up @@ -767,6 +802,7 @@ packages/
slack/ # Slack Web API, OAuth v2, incoming webhooks
apple/ # Apple Sign In / OIDC
microsoft/ # Microsoft Entra ID OAuth 2.0 / OIDC + Graph /me
auth0/ # Auth0 Authentication API, Management API v2, OIDC
aws/ # AWS S3, SQS, IAM, STS
apps/
web/ # Documentation site (Next.js)
Expand All @@ -790,4 +826,6 @@ Tokens are configured in the seed config and map to users. Pass them as `Authori

**Microsoft**: OIDC authorization code flow with PKCE support. Also supports client credentials grants. Microsoft Graph `/v1.0/me` available.

**Auth0**: Management API endpoints require a Bearer token obtained via `client_credentials` grant. Authentication API (`/oauth/token`) accepts `client_id`/`client_secret` in the request body or via Basic auth header.

**AWS**: Bearer tokens or IAM access key credentials. Default key pair always seeded: `AKIAIOSFODNN7EXAMPLE` / `wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`.
104 changes: 104 additions & 0 deletions packages/@emulators/auth0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# @emulators/auth0

Auth0 identity platform emulation with OAuth 2.0 / OIDC, Management API v2, user lifecycle, email verification, and log event streaming.

Part of [emulate](https://github.com/vercel-labs/emulate) — local drop-in replacement services for CI and no-network sandboxes.

## Install

```bash
npm install @emulators/auth0
```

## Endpoints

### Authentication API

- `POST /oauth/token` — token endpoint (client_credentials, password-realm, refresh_token)
- `GET /userinfo` — user profile from access token
- `POST /oauth/revoke` — revoke refresh token

### Management API v2

- `POST /api/v2/users` — create user
- `GET /api/v2/users/:id` — get user by ID
- `GET /api/v2/users-by-email` — search users by email
- `PATCH /api/v2/users/:id` — update user
- `POST /api/v2/tickets/email-verification` — create email verification ticket

### OIDC Discovery

- `GET /.well-known/openid-configuration` — OpenID Connect discovery
- `GET /.well-known/jwks.json` — JSON Web Key Set (RS256)
- `GET /_emulate/public-key.pem` — RSA public key in PEM format

### Inspector

- `GET /` — tabbed UI showing users, log events, OAuth clients, and connections

## Grant Types

| Grant type | Use |
|---|---|
| `client_credentials` | Machine-to-machine tokens (Management API access) |
| `http://auth0.com/oauth/grant-type/password-realm` | User login with email + password + connection |
| `refresh_token` | Exchange refresh token for new tokens |

## Log Event Streaming

The emulator dispatches Auth0 log events via webhook when state changes occur:

| Type | Event | Trigger |
|---|---|---|
| `ss` | Successful Signup | User created |
| `fs` | Failed Signup | Create user failed |
| `sv` | Email Verified | Verification ticket consumed |
| `scp` | Password Changed | User password updated |

Configure webhook subscribers in the seed config via `log_streams`.

## Error Fidelity

Error responses match Auth0's actual format so SDK error handling works unchanged:

- Authentication API errors use OAuth2 format: `{ error, error_description }`
- Management API errors use Auth0 format: `{ statusCode, error, message, errorCode }`

## Seed Configuration

```yaml
auth0:
connections:
- name: Username-Password-Authentication
users:
- email: admin@example.com
password: Admin1234!
email_verified: true
app_metadata:
role: ADMIN
oauth_clients:
- client_id: my-m2m-client
client_secret: my-secret
name: Backend Service
grant_types: [client_credentials]
audience: https://api.example.com
log_streams:
- url: http://localhost:9000/auth0-events
signing_key:
private_key_pem: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
public_key_pem: |
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
kid: my-custom-kid
```

When `signing_key` is omitted, a random RS256 key pair is generated on first request. When provided, all ID tokens and the JWKS endpoint use the configured key, enabling static JWT validation in your backend.

## Links

- [Full documentation](https://emulate.dev)
- [GitHub](https://github.com/vercel-labs/emulate)
47 changes: 47 additions & 0 deletions packages/@emulators/auth0/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@emulators/auth0",
"version": "0.4.1",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"homepage": "https://emulate.dev",
"repository": {
"type": "git",
"url": "https://github.com/vercel-labs/emulate.git",
"directory": "packages/@emulators/auth0"
},
"bugs": {
"url": "https://github.com/vercel-labs/emulate/issues"
},
"publishConfig": {
"access": "public"
},
"files": [
"dist"
],
"scripts": {
"build": "tsup --clean",
"dev": "tsup --watch",
"test": "vitest run",
"clean": "rm -rf dist .turbo",
"type-check": "tsc --noEmit",
"lint": "eslint src"
},
"dependencies": {
"@emulators/core": "workspace:*",
"hono": "^4",
"jose": "^6"
},
"devDependencies": {
"tsup": "^8",
"typescript": "^5.7",
"vitest": "^4.1.0"
}
}
Loading