Rsellz

Security posture

How we protect your data.

resellz handles operator records, retailer credentials, and inbound commerce email. This page describes the technical controls we run and how to reach our security contact.

Last reviewed: 2026-05-19.

Tenant isolation

Every per-user database operation runs inside a Postgres transaction that activates a non-privileged role (app_user) and binds the current user id to a session-local Postgres setting. Row-Level Security policies on every multi-tenant table reject reads and writes that don't match the bound user. The application role carries NOBYPASSRLS, so a misconfigured server action cannot accidentally read across tenants. A regression suite (scripts/test-rls.ts) attempts cross-tenant reads on every release.

Encryption at rest

Sensitive fields are encrypted at the column level with AES-256-GCM before they touch the database: gift card numbers and PINs, retailer account passwords used by the balance scanner, TOTP secrets and backup codes, Gmail refresh tokens, IMAP mailbox passwords, and Discord OAuth tokens. Keys are derived from a dedicated FIELD_ENCRYPTION_KEY environment secret. Each ciphertext carries a version prefix so future key rotation does not require a stop-the-world migration.

Transport and headers

All traffic is served over TLS 1.3 with HSTS preload. Response headers include a restrictive Content-Security-Policy,X-Frame-Options: DENY, a tight Permissions-Policy, and Cross-Origin protections. Session cookies are HttpOnly + Secure + SameSite=Lax, sealed with an iron-session secret.

Authentication

Passwords are hashed with bcrypt. TOTP (RFC 6238) two-factor authentication is supported via authenticator apps and one-time backup codes. Failed login attempts are rate-limited per IP and per account. Owner-account logins generate a real-time push notification so unauthorized access is visible immediately.

Webhook + integration auth

Stripe webhooks are verified with the official Stripe signature check on the raw request body. Discord interactions are verified with ed25519. Inbound webhooks require an HMAC-SHA256 signature generated with the slug's per-endpoint signing secret — slugs alone are not credentials. Outbound webhooks are validated against a private-IP allowlist (10/8, 127/8, 169.254/16, RFC1918, CGNAT, ULA) before the first network call and at every retry, to defend against SSRF and DNS-rebinding attacks.

Inbound email pipeline

When you connect Gmail (OAuth, read-only scope) or an IMAP mailbox, we read messages strictly to identify retailer confirmations, sales notifications, and shipping updates, and to extract structured fields. Personal correspondence is not processed. The full scope and retention rules are documented in the Privacy Policy. Gmail data is handled under Google's Limited Use requirements: no resale, no ads, no model training, no human access except for security investigations or your explicit consent.

Observability

Application errors are reported to Sentry. Every mutation writes an immutable activity-log row keyed to the originating user. The log survives user-side "wipe my data" actions — the trail is retained for chargeback, refund, and abuse investigations.

Backups + disaster recovery

Production data lives in Neon Postgres with point-in-time recovery enabled. We maintain documented procedures for encryption-key rotation, role-secret rotation, and full database restore. Disaster-recovery procedures are tested at least quarterly.

Reporting a vulnerability

Email security@rsellz.com with:

  • A description of the issue and where it lives
  • Steps to reproduce (or a minimal proof-of-concept)
  • The impact you believe a malicious party could cause

We acknowledge reports within 3 business days and target a fix (or mitigation) for high-severity issues within 14 days. We do not run a paid bounty program at this scale, but we credit reporters on this page with permission.

Please act in good faith: do not exfiltrate user data beyond the minimum needed to demonstrate the issue, do not run automated scans that degrade service, and do not access other users' data. We will not pursue researchers who follow these rules.

Incident-response commitment

If a security incident materially affects user data, we will: (1) notify affected users without undue delay and in line with applicable law, (2) provide a clear summary of what happened, what data was affected, and what we did about it, and (3) publish a post-mortem within 30 days of the incident closing.

Acknowledgments

No reports yet. If you'd like to be the first, see "Reporting a vulnerability" above.