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 includeSubDomains preload.
  • 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_id explicitly: 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 Unavailable rather 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.id so 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 to violations; Stripe webhook deduplication via stripe_session_id unique index; atomic spending-cap enforcement; security pipeline failing closed on infra outage; DOMPurify sanitization of preview HTML.
Last updated: September 1, 2026.