Skip to content

feat: Add Auth0 emulator#66

Open
cwheikki wants to merge 1 commit intovercel-labs:mainfrom
cwheikki:feat/auth0-emulator
Open

feat: Add Auth0 emulator#66
cwheikki wants to merge 1 commit intovercel-labs:mainfrom
cwheikki:feat/auth0-emulator

Conversation

@cwheikki
Copy link
Copy Markdown

I had attempted this a few years ago but with this project and modern tooling its much more effective now. This PR adds an emulator for the Auth0 APIs required to register, validate, and login as real user. This is now a working replacement for a live integration we have and it was as much of a drop-in replacement as you can get.


Summary

Add @emulators/auth0 package with Auth0 Authentication API, Management API v2, and OIDC emulation. Covers the OAuth token endpoint (client_credentials, password-realm, refresh_token), user CRUD, email verification tickets, and log event streaming via webhooks. Includes a tabbed inspector UI.

Why this matters

Testing Auth0 registration, login, and token flows currently requires hitting real Auth0 tenants (rate-limited, costs money, unreliable in CI) or mocking at the HTTP level. No existing emulator covers Auth0's Management API or its password-realm grant type (an Auth0 extension to OAuth2 that routes login to a named database connection).

With this emulator, the full identity flow can run locally: user registration (Management API) -> login (password-realm grant) -> token refresh -> email verification -> log event webhooks. All without network access.

Changes

New package: @emulators/auth0

Authentication API (/oauth/token):

  • POST with grant_type=client_credentials for Management API tokens
  • POST with grant_type=http://auth0.com/oauth/grant-type/password-realm for user login (returns access_token, refresh_token, id_token JWT)
  • POST with grant_type=refresh_token for token renewal
  • POST /oauth/revoke to revoke refresh tokens
  • GET /userinfo for authenticated user profile

Management API v2:

  • POST /api/v2/users to create users with email, password, connection, app_metadata
  • GET /api/v2/users/:id to fetch a user
  • GET /api/v2/users-by-email to search by email
  • PATCH /api/v2/users/:id to update user fields (including password, app_metadata merge)
  • POST /api/v2/tickets/email-verification to create verification tickets
  • GET /tickets/email-verification to consume a ticket (marks email as verified)

OIDC Discovery:

  • GET /.well-known/openid-configuration
  • GET /.well-known/jwks.json (RS256 key pair)
  • GET /_emulate/public-key.pem (RSA public key in PEM format)

Deterministic Signing Key:

  • Optional signing_key in seed config to provide a known RSA key pair for static JWT validation
  • When omitted, a random key pair is generated on first request (default behavior)
  • When provided, all ID tokens and the JWKS endpoint use the configured key
  • Custom kid supported, defaults to emulate-auth0-1

Log Event Streaming:

  • Dispatches Auth0 log events (ss, fs, sv, scp) via webhook on user creation, signup failure, email verification, and password change
  • Log events follow the canonical Auth0 log schema (log_id, date, type, user_id, user_name, client_id, client_name, connection, strategy, strategy_type, description)
  • Configurable via log_streams in seed config

Inspector UI (/):

  • Tabbed interface (Users, Log Events, OAuth Clients, Connections) using shared renderInspectorPage
  • User status badges (verified/unverified/blocked)
  • Log events displayed with type badges and timestamps

Error responses:

  • Authentication API uses OAuth2 format ({ error, error_description })
  • Management API uses Auth0 format ({ statusCode, error, message, errorCode })

Seed config

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

Changes outside @emulators/auth0

Registry and CLI wiring (standard for any new service):

  • packages/emulate/src/registry.ts: added auth0 to SERVICE_NAME_LIST and SERVICE_REGISTRY
  • packages/emulate/package.json: added @emulators/auth0 workspace dependency

seedFromConfig webhooks passthrough (needed for log stream subscriber registration):

  • packages/emulate/src/registry.ts: widened LoadedService.seedFromConfig signature to accept an optional 4th webhooks parameter
  • packages/emulate/src/commands/start.ts and api.ts: destructure webhooks from createServer() (already returned, previously unused) and pass it through to seedFromConfig

The webhooks parameter is optional, so all 12 existing emulators are unaffected — their seedFromConfig functions ignore the extra argument. Verified by running the full monorepo pnpm build and pnpm lint with no failures.

Root README.md: updated port listing (all 13 services), added Auth0 endpoint section, Auth section, and architecture tree entry. Also updated the service name list in the programmatic API options table. The port listing was previously stale (only 7 of 13 services listed) — this PR brings it current.

Testing

42 unit tests covering all endpoints, error response formats, log event dispatch, signing key configuration (deterministic and auto-generated), and edge cases (invalid PEM, half-configured keys, missing offline_access scope, blocked users). All pass against pnpm test, pnpm type-check, pnpm format:check, and pnpm lint.

Every endpoint was also manually tested against the running emulator via curl and an interactive browser-based test harness that exercises all API flows with inline assertions and a live log event stream.

Demo

auth0-emulator-demo.mp4

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 10, 2026

@cwheikki is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@cwheikki cwheikki changed the title feat: Add Auth0 Emulator feat: Add Auth0 emulator Apr 10, 2026
Add @emulators/auth0 package with:

- OAuth token endpoint (client_credentials, password-realm, refresh_token)
- Management API v2 (user CRUD, email verification tickets)
- OIDC discovery and JWKS (RS256)
- Log event streaming (ss, fs, sv, scp) via webhooks
- Deterministic signing key support for static JWT validation
- Tabbed inspector UI (Users, Log Events, OAuth Clients, Connections)
- 42 unit tests

Error responses match Auth0's actual API formats: OAuth2 format for the
Authentication API and Auth0's { statusCode, error, message, errorCode }
for the Management API.

Also passes webhooks through to seedFromConfig across all emulators
(optional parameter, backward-compatible) to enable log stream subscriber
registration from seed config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cwheikki cwheikki force-pushed the feat/auth0-emulator branch from 1ee4138 to 371b166 Compare April 10, 2026 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant