Before you make it public¶
vibecheck's /sessions and /verdict endpoints are bearer-gated, but the answer page (/s/{token}) is intentionally open — the token in the URL is the only credential, so anyone with the link can answer it. Before pointing a real VIBECHECK_BASE_URL at the public internet:
- Put a reverse proxy or CDN in front of it that rate-limits and caps request body size. vibecheck has no built-in rate limiting — an in-process limiter would be false security the moment you run more than one replica.
- Redact
/s/{token}from your proxy's access logs. That path is a bearer-equivalent secret. vibecheck keeps it out of its own structured logs and disables uvicorn's access log for this reason, but a default nginx/Caddy line in front of it will happily write the token to disk. - Set spend limits on your Anthropic API key. Real grading is one synchronous Claude call per screen submitted, plus two calls when the session is created (one to read the diff, one to write the questions), with no built-in per-deployment budget. Repeat work is cheap: an Explain click is stored and reused,
POST /sessionsreuses the session for a head SHA it has already seen, and a second submit for a screen already being graded is bounced, so the model cost per session is bounded by the number of questions timesMAX_QUESTION_ATTEMPTS, plus one explanation per question. The in-flight check is per-process, so it does not stop duplicates across replicas, and it does not replace rate limiting at your proxy. - Treat
VIBECHECK_TOKENas a real secret, and setVIBECHECK_ALLOWED_REPOSif you want a leaked token to not be usable against arbitrary repos. - Diffs are stored in Postgres in plaintext — scope database access like it holds source code, because it does.
vibecheck does ship a few defaults out of the box: interactive API docs (/docs, /redoc, /openapi.json) are disabled; Referrer-Policy, X-Content-Type-Options, X-Frame-Options and a Content-Security-Policy of default-src 'none'; style-src 'unsafe-inline'; script-src 'self' are sent on every response (the only script allowed is vibecheck's own same-origin paste guard — no inline script, no img-src, no connect-src — so the pages make no outbound requests at all, and there is nothing a session URL can leak to); request bodies are capped against bytes actually received rather than a client-supplied Content-Length; transient model-API failures are retried with backoff instead of surfacing to the developer; and session tokens are kept out of the logs.