Data Handling Policy

Conduit is designed as a governance proxy — MLS listing data transits through the system but is never persisted. This document describes how each data category is classified, stored, encrypted, and deleted.

Data classification

CategoryExamplesStorageSensitivity
Transit dataMLS listing records, property details, agent infoNever stored — transits through proxy onlyHigh
Audit metadataRequest counts, latency, status codes, field filter actionsSupabase PostgreSQL (append-only)Medium
Revenue recordsQuery costs, MLS/Conduit share, billing periodsSupabase PostgreSQLMedium
Organization dataOrg name, plan, MLS/vendor profiles, policiesSupabase PostgreSQLMedium
Auth credentialsAPI key hashes, OAuth tokens, session dataSupabase PostgreSQL + Cloudflare KV (cache)High
Billing dataStripe customer IDs, subscription status, payout recordsStripe (primary) + Supabase (references)High

What Conduit does NOT store

Conduit is a governance proxy, not a data warehouse. The following are never persisted:

  • MLS listing data (property records, photos, agent details)
  • Upstream MLS API responses (request bodies or response bodies)
  • Plaintext API keys (only SHA-256 hashes are stored)
  • User passwords (authentication is delegated to Supabase Auth / GitHub OAuth)
  • Credit card numbers or payment details (handled entirely by Stripe)
  • Vendor query content or search parameters

Encryption

At rest — All data stored in Supabase PostgreSQL is encrypted at rest using AES-256, managed by Supabase's infrastructure. Stripe stores billing data with PCI DSS Level 1 encryption.

In transit — All connections use TLS 1.2 or higher. This applies to: client → Cloudflare (proxy), client → Vercel (web app), proxy → Supabase (database lookups), proxy → MLS upstream server, web app → Stripe API.

API keys — Hashed with SHA-256 before storage. The original key is shown once at creation and cannot be retrieved.

Data deletion

Organization deletion — When an organization is deleted, all associated data is cascade-deleted: users, API keys, MCP servers, billing periods, usage events, and webhook configurations. Audit logs in mls_audit_log are retained for compliance (append-only, no delete).

Vendor suspension — When an MLS suspends a vendor via the kill switch, the vendor's access is revoked but data is preserved for audit purposes. The vendor can be reinstated.

API key revocation — Revoking a key sets its status to revoked and the key hash is invalidated in KV cache. The key record is retained for audit.

Third-party data processors

ProcessorPurposeData accessedCertifications
SupabaseDatabase, authenticationOrg data, auth, audit logs, revenue recordsSOC 2 Type II, HIPAA
CloudflareGateway proxy, KV store, edge computeRequest metadata, rate limit counters, API key cacheSOC 2 Type II, ISO 27001
VercelWeb application hosting, serverless functionsApplication code, session cookiesSOC 2 Type II
StripePayment processing, MLS payoutsCustomer IDs, subscription status, payout amountsPCI DSS Level 1, SOC 2 Type II

Known improvement areas

[i]Honest disclosure

We believe in transparent security posture. The following areas are identified for improvement and are being actively addressed.

Upstream MLS auth configuration

The upstream_auth_config field in the MCP servers table stores upstream MLS credentials in plaintext JSON. This should be migrated to an encrypted secrets manager (e.g., Supabase Vault or AWS Secrets Manager). Current mitigation: RLS restricts access to the owning organization, and the proxy reads credentials server-side only.

Audit log retention policy

Audit logs are currently retained indefinitely. A formal retention schedule with automated archival to cold storage should be implemented before the audit log grows beyond practical query performance limits.

Rate limit counter durability

KV-based rate limit counters may lose accuracy during Cloudflare edge propagation delays. Current mitigation: on KV failure, the system defaults to allowing the request and classifying it as included (preventing phantom billing). This is a deliberate fail-open for availability, documented in the system design.