Security

Brokerage data deserves enterprise discipline.

REHL handles lead PII, consent records, agent commission data, and the consumer behavior signals that power Heat. We isolate every brokerage at the database layer, enforce compliance in code, and keep our attack surface deliberately small. Below: exactly what we do, what we don't, and what's on the roadmap.

Tenant isolation

Every brokerage is fenced off at the database, not the app.

Multi-tenant SaaS platforms commonly enforce tenant separation in application code: every query filters by an org id, and a bug in any query is a cross-tenant leak. REHL doesn't rely on that.

We use Postgres Row-Level Security (RLS) policies on every brokerage-owned table. Each request carries an authenticated app.current_brokerage_id session variable; the database itself rejects any row that doesn't match. A buggy query that forgets to filter will return zero rows — not data from another brokerage.

Consumer-side data (saved listings, search alerts, preferences) uses a parallel RLS pattern keyed on app.current_consumer_id. One consumer can be a lead under multiple brokerages without those brokerages seeing each other's view of the same person.

A privileged super-admin role exists for REHL operators and bypasses RLS. Every super-admin context is logged with an actor + reason.

Compliance

TCPA, CAN-SPAM, and state-specific rules — designed as code, not policy.

Compliance is the leading source of regulatory risk in real estate outreach. The architecture below is what REHL enforces at the send-path before any message goes out — designed and documented today; activated channel-by-channel as each outreach surface ships. Until the corresponding pipe is live, the gate is enforced by the absence of any send-path at all.

  • Consent records. Every outreach recipient must have a consent record (channel, source, timestamp, IP, user-agent, exact disclosure text). No record, no send. Lead-capture forms already collect the disclosure + opt-in checkbox per the spec; the consent_records substrate that the send-gate reads is the next infra slice.
  • Suppression list. STOP / UNSUBSCRIBE / QUIT / CANCEL / END / OPTOUT on SMS auto- suppressed within seconds of receipt; CAN-SPAM unsubscribe + List-Unsubscribe headers per RFC 8058 on email. Triggered the moment the first SMS/email send-path ships behind the consent gate.
  • Quiet hours. SMS send-path enforces 8am–9pm in the recipient's local timezone. State rules layered on top: FL / WA / OK get double opt-in on SMS as a hard default.
  • A2P 10DLC. SMS blocked at the code level for any brokerage whose Twilio subaccount isn't A2P-registered. Not a soft warning.
  • Audit log. Every send writes an immutable outreach_events row with rendered message, recipient, consent reference, and idempotency key. Replay-ready for any inquiry.

Current implementation status, plainly: consent-capture UI live; consent-record persistence and the send-path gate are the next infra slice ahead of email/SMS outreach going live. We do not send messages today; when we do, every send goes through every gate above.

Data handling

Encrypted in transit and at rest. Region-locked. No silent data sharing.

  • TLS 1.2+ on every external connection. HSTS on consumer surfaces. Internal service-to-service traffic over private network.
  • Encryption at rest on the Neon-managed Postgres cluster (AES-256). Backups encrypted with the same standard.
  • us-east region only for v1. We won't silently expand data residency without a named brokerage-facing notice and a contract amendment.
  • No vendor sharing beyond what each brokerage explicitly opts into. The enrichment partners we use (identity resolution, contact verification, climate data) all process under DPAs that match what we tell brokerages in their contract.
  • Secrets management. All credentials in Fly secrets / Vercel env. No keys in repo. API keys for outbound services rotate on a schedule.

Application security

Hard between the consumer surface and internal services.

REHL ships as two distinct user-facing products that share one backend: app.rehl.us for brokerage users and rehl.us for consumers. The consumer surface never touches internal services directly.

  • Hardened public API. Consumer traffic goes through a narrow public-api service that exposes only what consumers need (active listings, save/alert ops, lead capture). Rate-limited per source. No admin endpoints.
  • No cross-consumer reads. RLS prevents a consumer from reading another consumer's saved data through a missing app-side filter or a forged identifier in the query. Session theft is a separate threat model, handled by short-lived session tokens, secure-cookie flags, and the auth provider's anomaly detection — not RLS.
  • Webhook signature validation on every inbound from Twilio, Postmark, Dropbox Sign, Stripe, and MLS feeds. Persisted raw, then processed asynchronously — replay possible if downstream fails.
  • Idempotency keys on every outbound external API call. Double-send across retries is structurally impossible.
  • Structured logging with brokerage_id, consumer_account_id, lead_id, and workflow_id on every relevant line. Sentry catches exceptions; nothing sensitive lands in error reports.

What's on the roadmap

What we're working toward, transparently.

REHL is early. Here's what's not done yet so we don't make claims we can't back up:

  • SOC 2 Type I — targeted for after our first commercial brokerage launches. We are not certified today; we will not claim otherwise.
  • Third-party penetration test — scheduled annually starting with the first commercial launch. Findings + remediation will be shareable under NDA on request.
  • Single sign-on / SAML — on the roadmap for brokerage-admin auth. Today: identity is handled through a dedicated auth provider with org-scoped membership.
  • Customer-managed encryption keys — for brokerages with bring-your-own-key requirements. On the backlog; not currently a v1 commitment.
Responsible disclosure

Found a vulnerability?

Email us at security@rehl.us with reproduction steps. We acknowledge within 2 business days, triage within 5, and patch on a severity-driven timeline. We don't prosecute good-faith research and we'll credit reporters who want credit.