Security Controls

Conduit enforces security at every layer of the request lifecycle. This document describes each control, its implementation, and where it operates in the stack.

1. Authentication & authorization

Every request to the Conduit gateway must present a valid credential. Two authentication methods are supported:

API keys — Generated per-organization with the format cdt_live_* (production) or cdt_test_* (sandbox). Keys are hashed with SHA-256 before storage — Conduit never stores plaintext API keys. Each key is scoped to an organization and inherits the organization's plan and permissions. Keys can be revoked instantly from the dashboard; revoked keys are rejected within seconds via KV cache invalidation.

OAuth 2.1 tokens — Full OAuth 2.1 authorization code flow with PKCE. Tokens are scoped (e.g., mcp:tools) and expire after a configurable TTL. Refresh tokens enable long-lived integrations without persistent credential storage. The gateway publishes OAuth Protected Resource Metadata at /.well-known/oauth-protected-resource.

bash
# API key authentication
curl -H "Authorization: Bearer cdt_live_abc123..." \
  https://gateway.conduitapi.dev/v1/org/server

# OAuth token authentication
curl -H "Authorization: Bearer eyJhbGciOi..." \
  https://gateway.conduitapi.dev/v1/org/server

2. Transport security

All communication uses TLS 1.2 or higher. Plaintext HTTP is never accepted.

LayerProviderTLS termination
Gateway proxyCloudflare WorkersCloudflare edge (TLS 1.2+, automatic certificate rotation)
Web applicationVercelVercel edge network (TLS 1.2+, automatic certificates)
DatabaseSupabaseSupavisor connection pooler (TLS 1.2+, managed certificates)
BillingStripeStripe API (TLS 1.2+, PCI DSS Level 1)

3. Vendor billing gate

Vendors accessing MLS-governed data must have an active Stripe subscription. The governance context resolver checks vendor_billing_status on every request. Vendors with inactive or canceled status receive a 402 response. Vendors with past_due status are allowed through with a warning header ( X-Conduit-Billing: past_due) to allow grace period resolution.

4. Rate limiting

Governance rate limiting uses sliding-window counters stored in Cloudflare KV. Each vendor-MLS pair is rate-limited independently across three windows defined by the MLS policy:

WindowKV key patternConfigurable by
Per minutegov_rl:{vendor}:{mls}:min:{ts}MLS policy
Per hourgov_rl:{vendor}:{mls}:hour:{ts}MLS policy
Per daygov_rl:{vendor}:{mls}:day:{ts}MLS policy

Rate limit state is returned in response headers: X-RateLimit-Remaining and X-RateLimit-Reset. When limits are exceeded, the gateway returns 429 with a retry_after value.

5. Field-level access control

MLS policies define visibility for each RESO field. Conduit maintains a registry of 60 standard RESO fields organized into 8 categories. Each field can be set to one of three visibility levels:

visibleField is included in the response as-is.
maskedField is present but value is replaced with a mask (e.g., partial address).
hiddenField is stripped entirely from the response.

Field filtering is applied after the upstream MLS server responds, operating on the JSON-RPC result body. This ensures the MLS sees its own data unfiltered while vendors receive only what the MLS policy permits.

6. Immutable audit trail

Every governed request is logged to the mls_audit_log table with append-only semantics enforced by PostgreSQL RLS policies:

sql
-- RLS prevents any modification to audit records
CREATE POLICY "No deletes on audit log"
  ON mls_audit_log FOR DELETE
  USING (false);

CREATE POLICY "No updates on audit log"
  ON mls_audit_log FOR UPDATE
  USING (false);

Each audit record captures: vendor identity, MLS identity, request method, response status, latency, fields filtered, billing classification (included vs overage), and revenue allocation. MLS admins can export audit logs as CSV or PDF from the dashboard.

7. Anti-training safeguards

Conduit enforces ephemeral data handling to prevent AI vendors from using MLS data for model training:

No caching — The proxy sets Cache-Control: no-store on all governed responses. MLS listing data is never cached at any edge.

No data persistence — Property data transits through the Cloudflare Worker and is never written to any Conduit datastore. Only metadata (request count, latency, field filter actions) is persisted.

Anti-training headers — Responses include headers signaling that content must not be used for training purposes.

Contractual enforcement — Vendor terms of service explicitly prohibit using MLS data for model training, fine-tuning, or embedding generation.

8. Kill switch

MLS administrators can instantly suspend a vendor's access via the dashboard kill switch. This sets mls_vendor_access.status to suspended and the change propagates to the gateway within the KV cache TTL (300 seconds maximum). For immediate effect, the governance context can be evicted from KV directly.

[!]Emergency procedure

In a P1 incident, platform administrators can also suspend access at the database level by updating mls_vendor_access.status directly. See the Incident Response Plan for full procedures.

9. Trust scanning

Conduit's automated trust scanner evaluates MCP servers across 5 dimensions using 28 individual tests. Scans produce findings with severity levels (critical, high, medium, low, info) and a composite trust score graded A+ through F. MLS administrators use trust scores to evaluate vendor access requests. See Trust Scoring for full details.

10. Database security

Conduit uses Supabase PostgreSQL with comprehensive row-level security:

RLS enabled on all tables — All 40 tables in the public schema have RLS enabled. 34 tables have explicit policies; the remaining tables default-deny (RLS enabled with no permissive policies equals zero access for non-service-role).

Organization-scoped access — Most policies use a get_user_org_id() helper function to restrict reads and writes to the authenticated user's organization.

Service-role isolation — Sensitive tables (OAuth tokens, Stripe events, Stripe transfers, vendor usage reports) are restricted to service_role only. No client-side access is possible.

Connection pooling — All database connections route through Supavisor with TLS, preventing direct PostgreSQL access from untrusted networks.

Audit log immutability — The mls_audit_log table has explicit DENY policies for UPDATE and DELETE operations, enforced at the database level.

[i]RLS audit

As of February 2026, all public-schema tables have RLS enabled. Service-role-only tables (OAuth, Stripe transfers, vendor usage reports) use explicit service-role policies. The audit log is append-only with database-level enforcement.