Security
How Xerish protects what matters.
The platform that carries generosity has to be worthy of it. Here's the engineering posture: where data lives, where money lives, what we measure, and how to report a vulnerability.
Defense in depth.
Xerish runs on Supabase (PostgreSQL with Row Level Security) and serverless edge functions. Every table in the public schema has RLS enabled, and policies are written against the acting user's JWT — never trusting client-supplied identifiers.
Database functions that touch financial state, admin actions, or webhook routes use Postgres' SECURITY DEFINER with a pinned search_path, and execution is revoked from the public role + anonymous role — they are reachable only by authenticated users (who hit internal role checks) or the trusted service-role token.
Long-running edge functions emit structured JSON logs to Supabase's log stream. Error capture across mobile + admin + website goes to Sentry.
Stripe is the ledger. Xerish does not hold funds.
Wallet balances are tracked in Xerish's database, but every dollar that backs them lives in Stripe's Connect ecosystem. Wallet top-ups create Stripe charges; gifts move funds from the giver's wallet to the recipient organization's Stripe Connect account directly — Xerish never custodies cash.
Every financial RPC (wallet top-up, gift, refund, withdrawal) uses an idempotency key supplied by the client, validated server-side. Double-tap races, retried network calls, and webhook redelivery cannot create double charges or double gifts.
Stripe webhook handlers verify HMAC signatures via Deno's SubtleCrypto implementation. Recipient organizations are required to have verified non-profit status before they can receive payouts.
Privacy by default.
Auth is email + password through Supabase Auth, with HaveIBeenPwned password-breach checking enabled. Mobile sessions are stored in expo-secure-store (iOS Keychain / Android Keystore), never in AsyncStorage. The Wallet and Treasury screens carry an opt-in Face ID / Touch ID gate.
Account deletion in-app is immediate: a server RPC anonymises the user's public profile (display name, photo, bio, location), cancels every active recurring gift, and signs them out in the same gesture. The auth row is hard-deleted by a daily worker. There is no waiting list.
The user-blocks list is reachable from Settings → Privacy & Safety. Blocking is bidirectional — blocked accounts cannot see the blocker's content either.
If you found something, tell us.
Xerish welcomes good-faith security research. We don't run a paid bounty program (yet), but every reported issue receives an acknowledgment within 72 hours and a credit in the security thank-you list at launch.
Email security@xerish.com with a description, reproduction steps, and the impact you observed. PGP key on request.
Please avoid: automated scanning against production, sending phishing to real users, testing against the test giver and church accounts (those are reserved for app-store reviewers), or exploiting a finding beyond what's needed to demonstrate it. We'll handle the cleanup; you handle the find.
The platform that carries generosity must be worthy of it.
Security is not a feature shipped once. It is the practice of a faithful steward.
Read the covenant →