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.
https://moqapi.dev/api/invoke/{projectId}/authSetup — Enable the Sandbox
Via the Dashboard (recommended)
- 1.Go to Auth Sandbox in the left sidebar.
- 2.Select the project you want to enable it for.
- 3.Click Enable Auth Sandbox.
- 4.A default OAuth client (client_id + client_secret) is created automatically.
- 5.A default test user (testuser / password123) is also created.
- 6.Copy the client_id from the Clients tab — you are ready to make token requests.
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_secretAll Endpoints at a Glance
Base: /api/invoke/{projectId}/auth
/authorize/token/userinfo/revoke/introspect/validate/basic/mfa/verify/.well-known/openid-configuration/.well-known/jwks.jsonAuth Type 1 — Client Credentials
machine-to-machineUsed for server-to-server communication where there is no user. Pass client_id and client_secret directly — no browser redirect needed.
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 appsThe 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
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
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-tokenStep 3 — Exchange code for tokens
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_tokenAuth Type 3 — Resource Owner Password
trusted clients onlyPass 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.
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_tokenAuth Type 4 — Refresh Token Rotation
automatic rotationExchange 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.
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-serviceA 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.
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 authValidate an X-API-Key header against registered clients. The client secret acts as the API key. Returns client info and allowed scopes.
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:passwordStandard HTTP Basic Authentication (RFC 7617). Pass Authorization: Basic base64(username:password) to authenticate a sandbox user and receive their profile.
# 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 testingEnable 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
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
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
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
# 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.
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.
# 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 — 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.
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 wrongexpired_token401Access token has expired — triggers refresh logicrate_limited429Too many requests — tests Retry-After handlingserver_error500Auth server error — tests 5xx error handlingManaging 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 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 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
}'