auth-healthcheck.py
auth-healthcheck.py
Script: tools/auth-healthcheck.py
Config: tools/auth-healthcheck.env (copy from tools/auth-healthcheck.env.example)
Report: auth-healthcheck-YYYYMMDD-HHMMSS.json (repo root, gitignored)
End-to-end production auth diagnostic for the Better Auth / Bloqr stack. Validates the full authentication chain from sign-up through session validation, then checks every backing store (KV, D1, Neon) and captures wrangler tail logs in the background.
What It Checks
| Step | Check | What it verifies |
|---|---|---|
| 1 | API health | GET /api/version responds, /api/auth/providers lists providers |
| 2 | Sign-up | POST /api/auth/sign-up/email creates a new test user |
| 3 | Sign-in + token | POST /api/auth/sign-in/email returns session.token, session.id, user object |
| 4 | Session validation | GET /api/auth/get-session with Bearer token returns the correct user |
| 5 | Email verification | user.emailVerified flag checked; warns if false |
| 6 | Better Auth KV | wrangler kv key list — verifies KV is accessible and shows key prefix distribution |
| 7 | D1 databases | Both DB (bloqr-backend-app-db) and ADMIN_DB (bloqr-backend-admin-db) — table list + row counts |
| 8 | Neon / PostgreSQL | Direct connection via psycopg2 — table row counts, test user row, session row |
| 9 | Admin API | GET /api/auth/admin/list-users with API key (optional) |
| 10 | Tail log summary | Worker exceptions and auth-related log events captured during the run |
Prerequisites
# One-time setup (from repo root)uv sync --directory tools
psycopg2-binaryis a self-contained PostgreSQL client — no Homebrew Postgres install required.
Configuration
cp tools/auth-healthcheck.env.example tools/auth-healthcheck.env# Edit tools/auth-healthcheck.envKey variables
| Variable | Required | Description |
|---|---|---|
NEON_URL | ✅ Yes | Direct Neon connection string. Get from Neon Console → Branch → “Direct connection” |
BETTER_AUTH_API_KEY | Optional | Enables admin API check (list-users). Leave blank to skip |
TEST_EMAIL | Optional | Fixed test email. Leave blank to auto-generate a unique email each run |
API_BASE | Optional | Defaults to https://api.bloqr.dev/api |
KV_BINDING | Optional | Defaults to BETTER_AUTH_KV |
D1_BINDING | Optional | Defaults to DB |
D1_ADMIN_BINDING | Optional | Defaults to ADMIN_DB |
ENABLE_TAIL | Optional | Set to false to skip wrangler tail. Defaults to true |
Running
# Using the shell alias (recommended)auth-check
# Or directlyuv run --directory tools python auth-healthcheck.pyThe script will:
- Start
wrangler tailin the background - Run all checks sequentially
- Wait a few seconds for tail to flush
- Print a rich summary table to the terminal
- Write a JSON report to the repo root
Interpreting Results
All green ✅
Auth is fully working. Sign-up, sign-in, session validation, KV writes, and Neon rows all succeeded.
session.token present ❌
The most critical failure. Means sign-in returned HTTP 200 but no token in the response body. Common causes:
storeSessionInDatabaseconflict with KV binding (fixed in PR #1725)- Prisma field mapping error —
displayName/namemismatch - Better Auth plugin (sentinel) crashing on init (fixed in PR #1724)
POST /auth/sign-in/email → HTTP 500 ❌
Worker is crashing during sign-in. Check tail logs section of the report for the exception.
emailVerified ⚠️
Normal for new sign-ups if requireEmailVerification=false. If sign-in is being blocked, this means requireEmailVerification=true is set and Resend is not delivering the verification email.
Session in Neon ⚠️ (not in Postgres)
Expected behaviour when storeSessionInDatabase=false (the default when KV is bound). Sessions live in KV only. This is correct and not a bug.
KV accessible ❌ or D1 execute ❌
Wrangler binding is not resolving. Check wrangler.toml binding names match the KV_BINDING / D1_BINDING values in your env file.
JSON Report
The report is written to auth-healthcheck-YYYYMMDD-HHMMSS.json at the repo root. Structure:
{ "timestamp": "2026-05-02T10:00:00", "api_base": "https://api.bloqr.dev/api", "results": { "POST /auth/sign-in/email": { "status": "PASS", "detail": "HTTP 200 OK", "data": {} } }, "errors": [ { "check": "session.token present", "detail": "missing — response keys: ['user']" } ], "summary": { "passed": 14, "failed": 1, "warnings": 2 }}Paste the contents of this file into a Copilot chat for instant root-cause analysis.
Wrangler Tail Logs
The script starts wrangler tail --format json in a background process and writes output to wrangler-tail.log (gitignored). The final section of the terminal output summarises:
- Worker exceptions (unhandled errors)
- Error-level log lines
- Auth-related log events (sign-in, sign-up, session, Prisma, Better Auth)
To watch the tail live in a separate terminal while the script runs:
tail -f wrangler-tail.log | jq '.logs[].parts[]'Relation to Other Docs
- Better Auth + Prisma — auth configuration reference
- Auth Chain Reference — how requests flow through the auth stack
- Neon Setup — how to get your
NEON_URL - Postman Testing — manual auth testing via Newman
- KB-001: API Not Available — if the script can’t reach the API at all
Bloqr AI™ — The privacy you didn't know you needed.
© 2026 Bloqr AI™, a trademark of Bloqr Systems™. Created by Bloqr Systems™, founded by Jayson Knight.
Internet Hygiene (n.) — the ongoing practices that keep your digital life clean, private, and safe.
Our product repos live in the BloqrAI org, part of the Bloqr Systems GitHub Enterprise. Product repos are internal-visibility — enterprise membership is required to view them.