Security
Concrete measures, not marketing claims, protecting every account and every pilot deployment. 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 Supabase 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: Cross-tenant reads are technically impossible. 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: April 17, 2026.