Skip to main content
ExactPour logo

Security

What we can show you in the product

This page describes controls that exist in the ExactPour codebase, migrations, and CI. If we cannot point at the code, we do not claim it.

Tenant isolation

Each customer account is a tenant. Postgres Row Level Security (RLS) is enabled on public tables, and FORCE RLS is applied so table owners cannot skip the policies. Tenant queries resolve the account from the profiles table through current_account_id(), not from a client-supplied account id.

CI replays the migration history and runs cross_tenant_isolation_smoke.sql plus function_grant_lockdown_smoke.sql. Those gates fail if a public RLS table is missing FORCE RLS, or if one tenant can read another tenant's rows.

Encryption in transit and at rest

exactpour.com is served over HTTPS. Production responses send Strict-Transport-Security with max-age=63072000, includeSubDomains, and preload. Database and API traffic to Supabase uses TLS.

Customer data lives in Supabase Postgres, hosted on AWS. Supabase encrypts that database at rest at the platform layer. ExactPour does not store a second application-level copy of disk encryption keys.

Access controls and roles

Account roles are OWNER, MANAGER, and STAFF. Policies and RPCs read the role from the profiles table through current_user_role(). JWT app_metadata is not trusted for authorization. Invites may only grant MANAGER or STAFF.

MASTER_ADMIN is a platform role for ExactPour staff. It is resolved server-side, not granted at signup, and admin actions are logged. Master-admin HTML and admin APIs require a second authentication factor (aal2).

Secret scanning and dependency gates

Every CI run on GitHub Actions scans the repository with Gitleaks. The scan is marked if: always() so a red dependency job cannot skip it.

The same pipelines run a fail-closed runtime npm audit (omit=dev, audit-level=high) and a full-tree audit with an expiring allowlist. New high or critical advisories fail the build.

Payments

Card collection happens on Stripe Checkout and the Stripe Customer Portal. ExactPour stores Stripe customer and subscription identifiers so we can open the portal and apply webhooks. We do not store card numbers, CVCs, or full track data.

Backups

The production database is hosted on Supabase. Supabase provides automated backups of that Postgres instance. Restore is an operator action from the Supabase project, not a self-serve customer control.

Vulnerability disclosure

Send a private report to security@exactpour.com. Include the affected URL or feature, what you observed, and a safe way to follow up. Do not put secrets, customer data, or exploit details in a public issue or public form.

Please stay inside what you need to show the issue. This page does not create a bug-bounty program or promise a reward or response deadline.

Email security@exactpour.com

Compliance roadmap

SOC 2 is planned. We do not claim a completed SOC 2 report, HIPAA coverage, an ISO certification, or a third-party penetration test.

Talk with ExactPour

Questions about ExactPour security?

For product questions, book a walkthrough. For a vulnerability, write security@exactpour.com. For a signed DPA, use the template page.

14-day trial available · No credit card · Typical reply within one business day