All Posts
OAuth 2.0AuthenticationTesting

Test OAuth 2.0 Flows Without an Identity Provider: The Auth Sandbox Approach

Kiran MayeeApril 10, 20259 min read

You're building an app that integrates with OAuth 2.0 for authentication. Before you can test the login flow, you need an authorization server. The typical options: spin up a free-tier Auth0 tenant, configure Keycloak in Docker, or mock the endpoints by hand. All of them have problems.

The IdP Setup Tax

Here's what it actually takes to test OAuth flows with a real identity provider:

  • Auth0 — create a tenant, configure a client app, set callback URLs, manage test users, handle rate limits on the free tier, deal with eventual consistency on user creation.
  • Keycloak — run a Docker container, configure a realm, create clients and users, hope the container doesn't eat 2GB of RAM on your local machine.
  • Firebase Auth — set up a Firebase project, enable providers, configure OAuth consent screen, manage service accounts.
  • Hand-rolled mocks — build your own /authorize, /token, /userinfo endpoints. Generate valid JWTs. Implement PKCE verification. Handle refresh tokens. Maintain it forever.

For integration testing, none of this makes sense. You don't need a production-grade identity provider — you need working OAuth endpoints that return valid tokens.

The Auth Sandbox Approach

moqapi.dev's Auth Sandbox gives you a fully functional OAuth 2.0 / OIDC server built into your project. Enable it with one click and you get:

  • Standard endpoints — /authorize, /token, /userinfo, /revoke, /introspect, /.well-known/openid-configuration, /.well-known/jwks.json
  • Real JWTs — RS256-signed access tokens and ID tokens with proper claims (sub, iss, aud, exp, iat, scope)
  • All grant types — authorization_code, client_credentials, refresh_token, password, jwt-bearer
  • PKCE support — S256 code challenge verification for SPAs and mobile apps
  • Refresh token rotation — old refresh tokens are automatically revoked when exchanged
  • OIDC discovery — standard discovery document and JWKS for library integration

Getting Started in 60 Seconds

Here's the complete setup:

  1. Go to Auth Sandbox in the moqapi.dev sidebar.
  2. Select a project and click Enable Auth Sandbox.
  3. A default client and test user are created automatically.
  4. Start making token requests immediately.
# Get an access token (client credentials)
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "moqapi_abc123",
    "client_secret": "your-secret",
    "scope": "openid profile email"
  }'

That's it. No tenant configuration, no Docker containers, no OAuth consent screens.

Testing the Full Authorization Code Flow

The authorization code flow is the most common OAuth flow for web apps. Here's how to test it with the sandbox:

# Step 1: Redirect to /authorize
GET /api/invoke/{projectId}/auth/authorize?
  response_type=code&
  client_id=moqapi_abc123&
  redirect_uri=http://localhost:3000/callback&
  scope=openid profile&
  state=random-state

# The sandbox auto-approves and redirects:
→ http://localhost:3000/callback?code=AUTH_CODE&state=random-state

# Step 2: Exchange code for tokens
POST /api/invoke/{projectId}/auth/token
{
  "grant_type": "authorization_code",
  "code": "AUTH_CODE",
  "redirect_uri": "http://localhost:3000/callback",
  "client_id": "moqapi_abc123"
}

# Returns: access_token, refresh_token, id_token

Testing Error Scenarios

The real value of a sandbox isn't testing the happy path — it's testing what happens when things go wrong. The Auth Sandbox supports configurable error injection:

{
  "errorSimulation": {
    "enabled": true,
    "errorRate": 30,
    "errorTypes": ["invalid_client", "expired_token", "rate_limited", "server_error"],
    "delayMs": 2000
  }
}

With error simulation enabled, 30% of requests will randomly return one of the configured error types. This lets you test:

  • Token refresh when the access token expires.
  • Retry logic when the auth server returns 503.
  • User-facing error messages for invalid_client or invalid_grant.
  • Timeout handling when the server adds artificial delay.

Library Integration via OIDC Discovery

Most OAuth libraries (next-auth, passport, oidc-client) support automatic configuration via OIDC discovery. Point them at the sandbox:

// next-auth configuration
export const authOptions = {
  providers: [
    {
      id: 'moqapi-sandbox',
      name: 'Test Auth',
      type: 'oidc',
      issuer: 'https://moqapi.dev/api/invoke/{projectId}/auth',
      clientId: 'moqapi_abc123',
      clientSecret: 'your-secret'
    }
  ]
};

The sandbox exposes /.well-known/openid-configuration and /.well-known/jwks.json so libraries auto-discover all endpoints and keys.

Key Takeaways

  • Setting up a real IdP for testing OAuth flows adds unnecessary complexity and cost.
  • The Auth Sandbox provides all standard OAuth/OIDC endpoints with real JWT tokens.
  • Error injection lets you test failure modes that are impossible to trigger on a real IdP.
  • OIDC discovery support means standard libraries work out of the box.
  • No Docker, no third-party accounts, no configuration — just enable and test.

Start testing auth flows in seconds at moqapi.dev/signup.

Share this article:

About the Author

Kiran Mayee

Founder and sole developer of moqapi.dev. Full-stack engineer with deep experience in API platforms, serverless runtimes, and developer tooling. Built moqapi to solve the mock data and deployment friction she experienced firsthand building production APIs.

Ready to build?

Start deploying serverless functions in under a minute.

Get Started Free