Auth Sandbox

Auth Sandbox

A fully-functional authentication server built into every moqapi.dev project. Test any auth flow — OAuth 2.0, PKCE, JWT Bearer, API Key, Basic Auth, and MFA — without configuring Auth0, Okta, Keycloak, or any identity provider.

Base URL for all auth endpoints: https://moqapi.dev/api/invoke/{projectId}/auth

Setup — Enable the Sandbox

Via the Dashboard (recommended)

  1. 1.Go to Auth Sandbox in the left sidebar.
  2. 2.Select the project you want to enable it for.
  3. 3.Click Enable Auth Sandbox.
  4. 4.A default OAuth client (client_id + client_secret) is created automatically.
  5. 5.A default test user (testuser / password123) is also created.
  6. 6.Copy the client_id from the Clients tab — you are ready to make token requests.
enable-via-api.shbash
curl -X POST https://moqapi.dev/api/auth-sandbox/config \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "projectId": "your-project-id", "enabled": true }'

# Response includes the generated default client_id and client_secret

All Endpoints at a Glance

Base: /api/invoke/{projectId}/auth

GET/authorize
POST/token
GET/userinfo
POST/revoke
POST/introspect
POST/validate
POST/basic
POST/mfa/verify
GET/.well-known/openid-configuration
GET/.well-known/jwks.json

Auth Type 1 — Client Credentials

machine-to-machine

Used for server-to-server communication where there is no user. Pass client_id and client_secret directly — no browser redirect needed.

client-credentials.shbash
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-client-secret",
    "scope": "openid profile email"
  }'

# Response
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid profile email"
}

The returned access_token is a real RS256-signed JWT you can decode at jwt.io to inspect claims.

Auth Type 2 — Authorization Code + PKCE

SPAs / mobile apps

The most secure OAuth 2.0 flow for public clients. PKCE prevents authorization code interception. Recommended for all frontend apps and mobile apps.

Step 1 — Generate PKCE pair

generate-pkce.jstypescript
const crypto = require('crypto');
const codeVerifier = crypto.randomBytes(32).toString('base64url');
const codeChallenge = crypto
  .createHash('sha256')
  .update(codeVerifier)
  .digest('base64url');
console.log({ codeVerifier, codeChallenge });

Step 2 — Redirect to /authorize

authorize-url.txttypescript
https://moqapi.dev/api/invoke/{projectId}/auth/authorize
  ?response_type=code
  &client_id=moqapi_abc123
  &redirect_uri=http://localhost:3000/callback
  &scope=openid profile email
  &state=random-csrf-token
  &code_challenge=YOUR_CODE_CHALLENGE
  &code_challenge_method=S256

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

Step 3 — Exchange code for tokens

token-exchange.shbash
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "AUTH_CODE_FROM_REDIRECT",
    "redirect_uri": "http://localhost:3000/callback",
    "client_id": "moqapi_abc123",
    "code_verifier": "YOUR_CODE_VERIFIER"
  }'

# Returns: access_token, id_token, refresh_token

Auth Type 3 — Resource Owner Password

trusted clients only

Pass username and password directly to get tokens. Only use for testing login forms or trusted first-party clients. The default test user is testuser / password123.

password-grant.shbash
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "password",
    "client_id": "moqapi_abc123",
    "client_secret": "your-secret",
    "username": "testuser",
    "password": "password123",
    "scope": "openid profile email"
  }'

# Returns: access_token, refresh_token, id_token

Auth Type 4 — Refresh Token Rotation

automatic rotation

Exchange a refresh token for a new access token + refresh token pair. The old refresh token is automatically revoked (rotation). This prevents refresh token replay attacks.

refresh-token.shbash
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "refresh_token",
    "refresh_token": "YOUR_REFRESH_TOKEN",
    "client_id": "moqapi_abc123",
    "client_secret": "your-secret"
  }'

# Old refresh_token is now invalid.
# Response contains a brand-new access_token + refresh_token pair.

Test short-lived tokens by setting accessTokenTTL: 10 (10 seconds) in the config. Wait 11 seconds, then verify the access token is rejected and refreshing works.

Auth Type 5 — JWT Bearer

service-to-service

A client presents a signed JWT assertion to get tokens. Used for service-to-service auth (RFC 7523). The JWT must be signed with the client secret via HS256.

jwt-bearer.jstypescript
const jose = require('jose');

const secret = new TextEncoder().encode('your-client-secret');
const assertion = await new jose.SignJWT({
  sub: 'moqapi_abc123',
  iss: 'moqapi_abc123',
  aud: 'https://moqapi.dev/api/invoke/{projectId}/auth/token',
  jti: crypto.randomUUID(),
})
  .setProtectedHeader({ alg: 'HS256' })
  .setExpirationTime('5m')
  .sign(secret);

// Then exchange the assertion for tokens:
const response = await fetch(
  'https://moqapi.dev/api/invoke/{projectId}/auth/token',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
      assertion,
      client_id: 'moqapi_abc123',
    }),
  }
);

Auth Type 6 — API Key Validation

simple key auth

Validate an X-API-Key header against registered clients. The client secret acts as the API key. Returns client info and allowed scopes.

api-key-validate.shbash
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/validate \
  -H "X-API-Key: your-client-secret"

# Response
{
  "valid": true,
  "client_id": "moqapi_abc123",
  "client_name": "Default Client",
  "scopes": ["openid", "profile", "email"]
}

# Invalid key response:
{
  "valid": false,
  "error": "invalid_api_key"
}

Use this endpoint in your backend middleware to validate API keys in your mock API. Register multiple clients (each with its own secret) to simulate multi-tenant API key auth.

Auth Type 7 — HTTP Basic Auth

username:password

Standard HTTP Basic Authentication (RFC 7617). Pass Authorization: Basic base64(username:password) to authenticate a sandbox user and receive their profile.

basic-auth.shbash
# Encode credentials: echo -n "username:password" | base64
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/basic \
  -H "Authorization: Basic dGVzdHVzZXI6cGFzc3dvcmQxMjM="

# Response
{
  "authenticated": true,
  "user": {
    "id": "usr_uuid",
    "username": "testuser",
    "email": "testuser@sandbox.moqapi.dev",
    "roles": ["user"]
  }
}

# Failed auth response (401):
{ "error": "invalid_credentials" }

Auth Type 8 — Multi-Factor Authentication (MFA)

2FA testing

Enable MFA on a sandbox user to test your app's two-factor authentication flow. When MFA is required, the password grant returns a challenge instead of tokens. The sandbox includes the MFA code in the response for easy testing.

Step 1 — Create a user with MFA enabled

create-mfa-user.shbash
curl -X POST https://moqapi.dev/api/auth-sandbox/users \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "configId": "your-sandbox-config-id",
    "username": "mfauser",
    "email": "mfa@sandbox.moqapi.dev",
    "password": "securepass",
    "mfaEnabled": true
  }'

Step 2 — Login triggers MFA challenge

mfa-login.shbash
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "password",
    "client_id": "moqapi_abc123",
    "username": "mfauser",
    "password": "securepass"
  }'

# Response (no tokens yet — MFA required):
{
  "error": "mfa_required",
  "mfa_token": "mfatk_abc123",
  "mfa_methods": ["totp"],
  "_sandbox_mfa_code": "847291"
}

The _sandbox_mfa_code field contains the code to use in Step 3. It is only returned in sandbox mode.

Step 3 — Verify the MFA code

mfa-verify.shbash
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/mfa/verify \
  -H "Content-Type: application/json" \
  -d '{
    "mfa_token": "mfatk_abc123",
    "code": "847291",
    "client_id": "moqapi_abc123"
  }'

# Response: full token set
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "refresh_token": "...",
  "id_token": "...",
  "token_type": "Bearer",
  "expires_in": 3600
}

Userinfo & Token Introspection

userinfo-introspect.shbash
# Get user profile from access token (OIDC Userinfo)
curl https://moqapi.dev/api/invoke/{projectId}/auth/userinfo \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Response
{
  "sub": "usr_uuid",
  "name": "testuser",
  "email": "testuser@sandbox.moqapi.dev",
  "email_verified": true,
  "roles": ["user"]
}

# Inspect a token (RFC 7662 Introspection)
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/introspect \
  -H "Content-Type: application/json" \
  -d '{ "token": "YOUR_ACCESS_TOKEN" }'

# Response
{
  "active": true,
  "sub": "usr_uuid",
  "client_id": "moqapi_abc123",
  "scope": "openid profile email",
  "token_type": "access_token",
  "exp": 1741443600
}

Revoking Tokens

Revoke access or refresh tokens. After revocation, introspection returns active: false. Useful for testing logout flows.

revoke.shbash
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/revoke \
  -H "Content-Type: application/json" \
  -d '{
    "token": "YOUR_TOKEN",
    "token_type_hint": "access_token",
    "client_id": "moqapi_abc123"
  }'

# Confirm revocation:
curl -X POST https://moqapi.dev/api/invoke/{projectId}/auth/introspect \
  -d '{ "token": "YOUR_TOKEN" }'
# → { "active": false }

OIDC Discovery & Library Integration

Standard OpenID Connect libraries (next-auth, oidc-client-ts, AppAuth) use the discovery document to auto-configure all endpoints. Point your library at the sandbox issuer.

oidc-discovery.shbash
# Discovery document (auto-configures all endpoints)
curl https://moqapi.dev/api/invoke/{projectId}/auth/.well-known/openid-configuration

# Public keys for JWT signature verification
curl https://moqapi.dev/api/invoke/{projectId}/auth/.well-known/jwks.json
next-auth-config.tstypescript
// next-auth — point at the sandbox
export const authOptions = {
  providers: [
    {
      id: "moqapi-sandbox",
      name: "Test Auth",
      type: "oidc" as const,
      issuer: "https://moqapi.dev/api/invoke/{projectId}/auth",
      clientId: "moqapi_abc123",
      clientSecret: "your-client-secret",
    },
  ],
};

Error Simulation

Configure the sandbox to randomly inject authentication errors. Essential for testing token refresh logic, retry behaviour, error messages, and timeout handling.

enable-error-simulation.shbash
curl -X POST https://moqapi.dev/api/auth-sandbox/config \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "projectId": "your-project-id",
    "errorSimulation": {
      "enabled": true,
      "errorRate": 30,
      "errorTypes": ["invalid_client", "expired_token", "rate_limited", "server_error"],
      "delayMs": 500
    }
  }'
invalid_client401client_id or client_secret is wrong
expired_token401Access token has expired — triggers refresh logic
rate_limited429Too many requests — tests Retry-After handling
server_error500Auth server error — tests 5xx error handling

Managing Clients & Users

Create multiple OAuth clients (each with its own client_id and client_secret) to simulate multi-tenant setups. Create multiple sandbox users with different roles for RBAC testing.

create-client.shbash
# Create a new OAuth client
curl -X POST https://moqapi.dev/api/auth-sandbox/clients \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "configId": "your-sandbox-config-id",
    "clientName": "Mobile App Client",
    "grantTypes": ["authorization_code", "refresh_token"],
    "redirectUris": ["myapp://callback"],
    "scopes": ["openid", "profile", "email"]
  }'
create-user.shbash
# Create a sandbox user with admin role
curl -X POST https://moqapi.dev/api/auth-sandbox/users \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "configId": "your-sandbox-config-id",
    "username": "adminuser",
    "email": "admin@sandbox.moqapi.dev",
    "password": "adminpass",
    "roles": ["admin", "user"],
    "mfaEnabled": false
  }'