Trust console · Privacy model
The query you ask is never written down.
Telemetry keeps a salted HMAC-SHA256 hash and a character count — enough to debug, rate-limit, and measure quality, and nothing that can reconstruct the question. This page summarizes docs/PRIVACY.md, which is the source of truth.
Enforcement
Where the guarantees are implemented
- Hashing: lib/crypto-utils.ts — HMAC-SHA256 with a secret HASH_SALT; same query, same hash; no way back to the text.
- Error reporting: lib/sentry-utils.ts — every Sentry event passes a beforeSend hook that scrubs sensitive fields (query, prompt, email, token…), strips auth headers and cookies, and replaces request bodies with hash + length.
- Rate limiting: lib/rate-limiter.ts — token bucket, 10 requests/min per IP; identifiers live in memory only and are cleaned up after inactivity.
- Database: the rag_docs table holds knowledge chunks only — zero user data, zero query logs; search embeddings are ephemeral.
Threat model
What this protects against — and what it cannot
Protected: database breach, log leakage, insider access, subpoena, analytics leakage — in every case there is no raw query to expose.
- OpenAI processes raw queries in transit per its terms — zero-retention configuration is documented in docs/PRIVACY.md.
- Transport security relies on HTTPS/HSTS; the headers are enforced in proxy.ts.
- Queries exist briefly in server memory while being answered — that is inherent to answering them.
- Not HIPAA-compliant out of the box; the hardening path (BAAs, at-rest encryption, audit logging) is documented.
Verify it yourself
Verify it yourself
curl -X POST https://csbrainai.vercel.app/api/answer \
-H "Content-Type: application/json" \
-d '{"query":"What is RAG?"}'
# the response returns q_hash and q_len — exactly what was retainedSource of truth: docs/PRIVACY.md (threat model, GDPR/CCPA/HIPAA notes, audit checklist, incident response) · implementation: lib/crypto-utils.ts, lib/sentry-utils.ts, lib/rate-limiter.ts