Security
Concrete measures, not marketing claims, protecting every account. Audited during our launch readiness review on 2026-04-17.
Encryption
- In transit: TLS 1.3 on every public endpoint. HTTP Strict Transport Security (HSTS) enforced with a 2-year max-age and
includeSubDomainspreload. - At rest: AES-256 on the application database (Supabase-managed Postgres 17). File uploads encrypted at rest in Vercel Blob storage.
- Secrets: Application secrets are never logged. They live in Vercel environment variables, segregated per environment.
Access control & data isolation
- Row Level Security (RLS) is enabled on every table holding user data: profiles, conversations, messages, violations, moderation logs, billing transactions, user memories. Each policy scopes reads to
auth.uid() = user_id. - Customer isolation: Row Level Security denies cross-tenant reads at the database, so an application bug alone cannot expose data belonging to another account. Admin client usage is limited to billing and security paths and always filters by
user_idexplicitly: defense in depth on top of RLS.
Authentication
- Supabase Auth with password hashing via bcrypt.
- Google OAuth supported for customers who prefer SSO.
- Session cookies are HttpOnly, Secure, and SameSite=Lax.
- Post-auth redirects are validated as same-site paths: no open-redirect exposure.
Moderation & abuse prevention
- Every chat message passes through a layered pipeline: rate-limit check, input sanitization, local content moderation (jailbreak and spam detection), progressive violation penalties.
- Default-deny posture: when a security dependency (Redis, Supabase) is unavailable, requests return
503 Service Unavailablerather than bypassing checks. - Progressive violation penalties: 10 min → 1 hour → 24 hour → 7 day → permanent. Zero tolerance for CSAM, terrorism, credible threats against persons, or content sexualizing minors.
- Rate limits enforced per user, per endpoint, and per client IP through Upstash Redis, with a bounded in-memory fallback if Redis is unavailable.
Billing & payment security
- All payments flow through Stripe. JCIL.AI never receives card numbers; we're out of PCI-DSS scope.
- Stripe webhooks are verified with Stripe's signed payload and de-duplicated by
session.idso retries cannot double-credit. - Atomic charge + monthly-cap checks live in a single Postgres function to prevent race conditions under concurrent chat requests.
Vulnerability disclosure
If you believe you've found a security issue in JCIL.AI, please report it through the compliance contact form with topic: security. We respond within 48 hours, acknowledge good-faith reporters, and do not pursue legal action against researchers following coordinated disclosure.
Machine-readable disclosure info lives at /.well-known/security.txt per RFC 9116.
Change log
- 2026-04-17: Launch readiness audit closed these gaps: row level security added to
moderation_logs; explicit policies added toviolations; Stripe webhook deduplication viastripe_session_idunique index; atomic spending-cap enforcement; security pipeline failing closed on infra outage; DOMPurify sanitization of preview HTML.
Last updated: September 1, 2026.