Security
How we protect your data
Short version: your portfolio is isolated at the database level, encrypted in transit and at rest, and never used to train AI models. Detail below.
Row-level isolation
Every tenant-facing table has Postgres Row Level Security policies that enforce:
- A landlord can only read rows where
organization_idmatches an org they own. - A tenant can only read rows tied to their own
tenant_id. - Service-role writes (Stripe webhooks, cron) are explicitly scoped and audited.
RLS is evaluated by Postgres itself, which means a bug in our application code still can't expose another landlord's data.
Encryption
- In transit: TLS 1.2+ everywhere, HSTS on tenant-assist.com.
- At rest: AES-256 on Postgres storage (Supabase/AWS), encrypted object storage for uploaded photos and lease documents.
- Secrets: API keys stored as SHA-256 hashes; webhook signing secrets are per-endpoint, generated at creation.
- Passwords: hashed via Supabase Auth (bcrypt with per-user salts).
Authentication
- Email + password auth via Supabase, with optional magic-link sign-in.
- Session cookies are
HttpOnly; Secure; SameSite=Lax. - All landlord API routes verify role + org ownership before returning data.
- Vendor portal uses single-use magic tokens (no login for vendors) with 30-day expiry.
Audit & integrity
- Every lease signature is recorded with IP, user agent, typed name, and a SHA-256 hash of the rendered document.
- Stripe webhook deliveries and outbound TenantAssist webhooks are logged with attempt counts and last error.
- Admin writes to billing columns are blocked at the database level for landlord JWTs; only service role can write.
Incident response
We target a <1-hour acknowledgment, <4-hour mitigation, and <72-hour customer notification window for anything that touches customer data. Incidents are posted to /trust.
Report a suspected issue to tenantassist@protonmail.com — responsible disclosure is welcomed and we do not pursue legal action against good-faith researchers.
Access control
- Least-privilege: production database access is limited to two maintainers.
- All engineer access is 2FA-enforced and logged.
- Production secrets are stored in Cloudflare secret bindings, never in git.
- Backups are encrypted and retained for 30 days.
Subprocessors
These vendors process customer data on our behalf. We disclose changes 30 days in advance on the trust page.
| Subprocessor | Purpose | Location |
|---|---|---|
| Supabase (Postgres, Auth, Storage) | Primary application database, auth, and file storage | US (AWS us-east-1) |
| Cloudflare Workers | Application compute and edge delivery | Global edge |
| Stripe | Payment processing (subscriptions + rent collection) | US |
| Resend | Transactional email delivery | US |
| OpenAI | AI maintenance triage (tenant messages only; never trains on your data) | US |
Data processing addendum (DPA)
For customers who need a signed DPA for GDPR or state-level privacy compliance, we have a standard template ready to go.
Questions?
Security-sensitive deals often need more detail than a public page can provide. We're happy to fill out security questionnaires and walk through our architecture.