quizbase
Skip to content
Command Palette
Search for a command to run...
QuizBase · Docs

Authentication#

Every /api/v1/* request — except /api/v1/report (anonymous bug submission) — requires an API key. Quota is per user account, shared across all your keys (up to 20 active).

Key prefixes#

PrefixPurposeBrowser-safe (CORS)
qb_pk_*Publishable — safe to embed in client bundles (browsers, mobile apps).Yes — sends Access-Control-Allow-Origin: *
qb_sk_*Secret — backend only. Don’t ship in client bundles.No — browsers will block cross-origin use

Passing the key#

Send your key in the X-API-Key header. Authorization: Bearer <key> also works.

Rotation#

Rotate keys from the dashboard. When you rotate:

  1. Create the new key first.
  2. Deploy the new key alongside the old one in your environment.
  3. Delete the old key after your traffic has drained to the new key (check dashboard usage).

The rotated old key keeps working for 24h as a grace period — no downtime, no broken requests.

Storage#

  • Server: environment variables (QUIZBASE_KEY), never committed files.
  • Client (browser/mobile): only qb_pk_*. Consider a server-side proxy if you want to hide the key entirely — it costs you a hop but stops key extraction.
  • CI: encrypted secrets (GitHub Actions, GitLab CI, Railway variables).

Public endpoint (no key needed)#

One endpoint is public — anonymous-by-design with per-IP rate limit:

  • POST /v1/report — translation / factual / attribution / inappropriate problem reports. Rate-limited 5/min per IP.

Every other endpoint requires an API key.

CORS — when browser fetch works#

  • /v1/report: open CORS — fetch from any origin works without a key.
  • Authenticated endpoints with qb_pk_*: CORS header set. Browser fetch from any origin works — that’s what publishable keys are for.
  • Authenticated endpoints with qb_sk_*: no CORS header. Browsers block these requests by design. Secret keys aren’t meant to ship in browser bundles.

OPTIONS preflight returns 204 with Access-Control-Allow-Methods: GET, POST, OPTIONS and Allow-Headers: Authorization, Content-Type, X-API-Key, X-Request-Id.

There is no per-key origin allowlist today — any origin can use a pk_* key. Rotate the key (and optionally revoke the old one) if you need to invalidate it.

OAuth 2.1 (for AI agents on /mcp)#

QuizBase implements OAuth 2.1 with Dynamic Client Registration for the MCP server. This is the path Claude.ai web/desktop/mobile Custom Connectors, ChatGPT custom connectors, Gemini agents, and MCP Inspector take by default — the surface handles the flow without exposing a key to the user.

API keys (qb_pk_* / qb_sk_*) remain the authentication for /api/v1/* REST endpoints. The rule is OAuth for agents, API key for code.

Discovery endpoints#

EndpointWhat it returns
/.well-known/oauth-protected-resourceRFC 9728: resource, authorization_servers, scopes_supported, bearer_methods_supported, signing algs
/.well-known/oauth-authorization-serverRFC 8414: authorization_endpoint, token_endpoint, registration_endpoint, jwks_uri, code_challenge_methods_supported: ["S256"], grant types, scopes
/api/auth/jwksJWKS — EdDSA Ed25519 public keys for verifying access tokens locally

Scopes#

ScopeGrants
openidOIDC standard — emits sub (user id)
profileUser’s display name
emailUser’s email address
offline_accessRefresh tokens (required for long-lived agent sessions)
quizbase:readRead every public-data tool on /mcp (quizbase_random, quizbase_list, …, quizbase_report)

Token lifetime#

  • Access token (JWT, EdDSA-signed): 1 hour. Sent as Authorization: Bearer <jwt> to /mcp. The token carries aud = https://quizbase.runriva.com/mcp — sending it to any other audience fails verification.
  • Refresh token: 90 days, rotates on every use. AI agent sessions can last weeks, so we lean long; rotation contains the blast radius.

Revoking an OAuth grant#

To revoke access for a specific app:

  1. Note the client name shown on the consent screen (e.g. “Claude”, “MCP Inspector”).
  2. Email quizbase@gmail.com with the client name and your account email. We confirm and revoke within one business day.

Next#